تشغيل الخادم
تثبيت الخادم
كيف تثبّت خادم Pabal وتشغّله باستخدام Docker Compose على خادم واحد متاح على الإنترنت.
هذه طريقة تثبيت خادم Pabal على خادم واحد متاح على الإنترنت. تشغّل باستخدام Docker Compose ثلاث حاويات هي خادم Pabal · PostgreSQL · Caddy (HTTPS)، وتربط كل البيانات التي يجب ألا تضيع بمجلدات على المضيف (bind mount). اتبع الخطوات بالترتيب من الأعلى إلى الأسفل.
النطاق pabal.me، وعنوان IP العام للخادم 203.0.113.10 (عنوان للتوضيح — ضع مكانه عنوانك الحقيقي عند القراءة)، ومكان الشيفرة المصدرية /opt/pabal، ومكان البيانات /srv/pabal، ونظام التشغيل Ubuntu 24.04 LTS. والملفات اللازمة موجودة في المجلد deploy/ من المستودع.
نظرة سريعة
شرح المخطط
- ثلاث مناطق: المستخدمون على الإنترنت ← الحاويات الثلاث على خادم الإنتاج ← المجلدات المربوطة على قرص المضيف. يمكن حذف الحاويات وإعادة إنشائها في أي وقت، أما كل ما يجب أن يبقى ففي
/srv/pabal. - لا يوجد إلا مدخلان: يتصل التطبيق بالخادم مباشرة عبر منفذ MTProto (لا حاجة إلى HTTPS لأنه يشفّر بنفسه)، أما الموقع والوثائق وBot API فتمر عبر المنفذ 443 في Caddy. ويحجب Caddy مسارات الإدارة (
/admin،/health…) ولا يمرّر إلا الباقي. - الخط الأحمر المتقطع طريق خاص بالمشغّل. فصفحة الإدارة مفتوحة فقط على
127.0.0.1:8080في الخادم، ولا يُدخل إليها إلا عبر نفق SSH. أما PostgreSQL فليس له منفذ مفتوح إلى الخارج أصلاً. - المربعان الأحمران هما أهم البيانات. مفتاح RSA في
pabal_server/keysيُضمَّن في التطبيق عند بنائه، فإذا فقدته فعليك إعادة توزيع كل التطبيقات، وpostgres_data/يحتوي على كل الحسابات والمحادثات. فهما في رأس أولويات النسخ الاحتياطي. - الأسهم الرمادية تعني التخزين: يكتب الخادم المفاتيح والصور والإعدادات والسجلات، ويكتب PostgreSQL الأحداث، ويكتب Caddy الشهادات، كلٌّ في مجلده.
المتطلبات
| البند | التفاصيل |
|---|---|
| الخادم | Ubuntu 24.04 LTS، وللبداية 2 vCPU · 4 GB RAM · 40 GB SSD. ومع ازدياد المستخدمين والرسائل زِد الذاكرة أولاً |
| عنوان IPv4 عام | عنوان IP ثابت. فالتطبيق يُبنى وعنوان الخادم فيه بصيغة IP، والخادم كذلك يُبلغ التطبيق بعنوانه بصيغة IP |
| النطاق | نطاق واحد يمكنك تعديل DNS الخاص به (سجل A) |
| وسيلة إيصال رموز التسجيل | حساب واحد لـ SMS (Twilio · Solapi · webhook) أو للبريد الإلكتروني (SMTP) |
| جهاز Mac | جهاز Mac لبناء التطبيق (Pabal.app) لهذا الخادم |
المنافذ
| المنفذ | من يستخدمه | الفتح | الوصف |
|---|---|---|---|
| 22/tcp | المشغّل | يُنصح بعنوان IP المشغّل فقط | SSH |
| 80/tcp | Caddy | للجميع | إصدار الشهادات · التحويل إلى HTTPS |
| 443/tcp, 443/udp | Caddy | للجميع | الموقع · الوثائق · Bot API (وudp لـ HTTP/3) |
| 8443/tcp | الخادم | للجميع | اتصال التطبيق (MTProto) |
| 8080/tcp | الخادم | لا يُفتح | صفحة الإدارة · فحص الصحة — على 127.0.0.1 في الخادم فقط |
| 5432/tcp | PostgreSQL | لا يُفتح | على الشبكة الداخلية للحاويات فقط |
المنفذ 443 يستخدمه الموقع (HTTPS). وMTProto ليس HTTP ولا TLS، فلا يمكن تقاسم منفذ واحد بينهما. وإذا أردت أن يستقبل التطبيق أيضاً على 443، بسبب شبكات الشركات والمدارس التي تحجب المنافذ غير المألوفة، فاحصل على عنوان IP إضافي وخصّص المنفذ 443 على ذلك العنوان للخادم (في .env اجعل PUBLIC_IP هو العنوان الثاني، وMTPROTO_PORT=443، وافصل بينهما بإضافة عنوان IP إلى المنافذ في ملف Compose). ولأن الخادم يُبلغ التطبيق «اتصل بهذا المنفذ على هذا العنوان»، اجعل منفذ التطبيق داخل الحاوية وخارجها واحداً.
1. تجهيز الخادم
sudo apt update && sudo apt -y upgrade
timedatectl # تحقق من ظهور "System clock synchronized: yes"
مزامنة الوقت ضرورية. فأرقام رسائل MTProto مشتقة من الوقت، وإذا انحرفت ساعة الخادم يكرّر التطبيق محاولات الاتصال. وإذا ظهرت no فنفّذ sudo timedatectl set-ntp true.
# جدار الحماية
sudo ufw allow OpenSSH # إن أمكن: sudo ufw allow from <IP المشغّل> to any port 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw allow 8443/tcp
sudo ufw enable
# Docker (سكربت التثبيت الرسمي)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER # بعد إعادة تسجيل الدخول يعمل docker دون sudo
docker compose version # الإصدار v2 أو أحدث
المنافذ التي يفتحها Docker (ports:) تُفتح بغض النظر عن قواعد ufw. لذلك لا يفتح ملف Compose إلا المنافذ العامة (80 و443 و8443)، ويفتح منفذ الإدارة على 127.0.0.1:8080 فقط، ولا يفتح PostgreSQL أصلاً. تذكّر ذلك عندما تعدّل ports:.
2. جلب الشيفرة المصدرية
sudo mkdir -p /opt/pabal && sudo chown $USER: /opt/pabal
git clone <عنوان المستودع> /opt/pabal
إذا كنت تنسخ من حاسوب التطوير فلا ترسل المفاتيح والبيانات والسجلات (rsync --exclude 'keys/' --exclude 'data/' --exclude 'logs/' --exclude '**/target/'). فمفتاح RSA لخادم الإنتاج يُنشئه خادم الإنتاج بنفسه عند أول تشغيل — وإذا استخدمت مفتاح التطوير في الإنتاج يصبح حاسوب التطوير ذاك مكاناً قادراً على فك تشفير حركة الإنتاج.
3. مجلدات البيانات (bind mount)
sudo mkdir -p /srv/pabal/{postgres_data,pabal_server/keys,pabal_server/data,pabal_server/logs,caddy/data,caddy/config,backups}
sudo chown -R 1000:1000 /srv/pabal/pabal_server # تعمل حاوية الخادم بالمعرّف uid 1000
sudo chown -R $USER: /srv/pabal/backups
sudo chmod 700 /srv/pabal/pabal_server/keys /srv/pabal/backups
| المجلد | داخل الحاوية | المحتوى | إذا فُقد |
|---|---|---|---|
pabal_server/keys | /app/keys | private.pem (مفتاح RSA الخاص بالخادم)، private.pem.pub | إعادة بناء كل التطبيقات وتوزيعها |
pabal_server/data | /app/data | الصور (media/)، وadmin-token، وoperations.json (إعدادات رموز التسجيل وSMS وSMTP، بما فيها القيم السرية) | الصور وإعدادات التشغيل |
pabal_server/logs | /app/logs | سجلات الخادم (تُضغط يومياً) | السجلات فقط |
postgres_data | /var/lib/postgresql/data | كل الحسابات والمحادثات والرسائل وتسجيلات الدخول والبوتات وإعدادات webhook | الخدمة بأكملها |
caddy/data، caddy/config | /data، /config | شهادات HTTPS | تُصدر من جديد |
backups | (على المضيف فقط) | نتائج backup.sh | — |
4. ملف الإعدادات .env
cd /opt/pabal/deploy
cp .env.example .env
chmod 600 .env
openssl rand -base64 30 | tr -d '/+=' | cut -c1-32 # ضع القيمة الناتجة في POSTGRES_PASSWORD
nano .env
DOMAIN=pabal.me
PUBLIC_IP=203.0.113.10
POSTGRES_PASSWORD=(القيمة التي أنشأتها أعلاه)
PABAL_HOME=/srv/pabal
PABAL_SOURCE=..
PABAL_NETWORK=ssemiya-net
MTPROTO_PORT=8443
HTTP_PORT=80
HTTPS_PORT=443
ADMIN_PORT=8080
ADMIN_TOKEN=
JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=100"
| القيمة | ما تضعه | ملاحظات |
|---|---|---|
DOMAIN | نطاق الموقع | الروابط التي ينشئها التطبيق (pabal.me/اسم_المستخدم)، وعناوين الوثائق، ومعاينات الروابط، كلها بهذا العنوان |
PUBLIC_IP | عنوان IPv4 العام للخادم | في الخدمات السحابية هو العنوان العام الظاهر في لوحة التحكم (وليس العنوان الخاص داخل الخادم) |
POSTGRES_PASSWORD | قيمة عشوائية | حدّدها قبل التشغيل الأول. فـ PostgreSQL لا يستخدم هذه القيمة إلا عند إنشاء مجلد البيانات أول مرة |
PABAL_HOME | /srv/pabal | مجلد الخطوة 3 |
PABAL_SOURCE | .. | المستودع الذي تُبنى منه صورة الخادم: .. إذا بقي ملف compose داخل deploy/ في المستودع، وإلا فمسار الشيفرة المصدرية |
PABAL_NETWORK | ssemiya-net | شبكة Docker التي تنضم إليها الحاويات الثلاث. أنشئها مسبقاً (الخطوة 6) |
MTPROTO_PORT | 8443 | إذا غيّرته فغيّر معه جدار الحماية وبناء التطبيق |
ADMIN_TOKEN | اتركه فارغاً | إذا تُرك فارغاً يُنشأ عند التشغيل الأول في pabal_server/data/admin-token. وإذا أردت تحديده بنفسك فليكن 16 حرفاً على الأقل |
JAVA_OPTS | القيمة الافتراضية | إذا لم تكفِ الذاكرة فارفع -Xmx (حتى نحو نصف ذاكرة الخادم) |
يشغّل ملف Compose الخاص بالإنتاج الخادمَ وأرقام الاختبار معطّلة (TELEGRAM_TEST_NUMBERS=false). والقائمة الكاملة لقيم الإعدادات التي يقرؤها الخادم موجودة في الإدارة والإعدادات — متغيرات البيئة.
5. DNS
| الاسم | النوع | القيمة |
|---|---|---|
pabal.me | A | 203.0.113.10 |
www.pabal.me | A | 203.0.113.10 |
dig +short pabal.me # يجب أن يظهر 203.0.113.10 (قد يستغرق سريان التغيير من دقائق إلى ساعات)
يمكنك التشغيل قبل أن يشير DNS إلى الخادم، فسيعيد Caddy المحاولة تلقائياً حتى يحصل على الشهادة.
6. البناء والتشغيل
cd /opt/pabal/deploy
docker network inspect ssemiya-net >/dev/null 2>&1 || docker network create ssemiya-net # مرة واحدة فقط
docker compose up -d --build # في المرة الأولى بضع دقائق (ينزّل Maven المكتبات)
docker compose ps # تظهر pabal-server وpabal-postgres وpabal-caddy بحالة running (healthy)
docker compose logs -f pabal-server # للخروج اضغط Ctrl+C
عند التشغيل الأول تظهر في السجل أسطر مثل هذه.
WARN ServerKeys - Generated a new RSA key at /app/keys/private.pem (fingerprint -3898654385185406269). Clients must embed /app/keys/private.pem.pub
INFO TelegramServer - JDBC persistence active (jdbc:postgresql://pabal-postgres:5432/pabal)
INFO BotFather - BotFather is user 100000
INFO AdminToken - Created the admin token in /app/data/admin-token
INFO TelegramServer - Website: http://0.0.0.0:8080/ (published at https://pabal.me/)
- السطر الأول بمستوى WARN لكنه طبيعي (تنبيه بأن المفتاح يُنشأ مرة واحدة فقط). وفي المرات التالية يظهر
Loaded RSA key … (fingerprint …). والبصمة تختلف من خادم إلى آخر. - ينشئ الخادم الجداول بنفسه عند التشغيل.
7. التحقق
# من الخارج (من حاسوبك)
curl -sI https://pabal.me/ | head -1 # HTTP/2 200
curl -s -o /dev/null -w '%{http_code}\n' https://pabal.me/docs/ # 200 — هذه الوثائق
curl -s -o /dev/null -w '%{http_code}\n' https://pabal.me/admin/ # 404 — صفحة الإدارة غير منشورة
curl -s https://pabal.me/docs/server-key.pem | head -1 # -----BEGIN RSA PUBLIC KEY-----
nc -vz 203.0.113.10 8443 # succeeded — منفذ التطبيق
# على الخادم
curl -s http://127.0.0.1:8080/health # {"status":"UP",…}
ls -l /srv/pabal/pabal_server/keys # private.pem(600), private.pem.pub
8. صفحة الإدارة والإعدادات الأولى
# على حاسوبك (اتركه يعمل)
ssh -N -L 8080:127.0.0.1:8080 <user>@203.0.113.10
# الرمز المميّز للإدارة تجده على الخادم
sudo cat /srv/pabal/pabal_server/data/admin-token
افتح http://localhost:8080/admin/ في المتصفح وأدخل الرمز المميّز. الإعدادات التي يجب ضبطها قبل التشغيل الفعلي (التفاصيل في الإدارة والإعدادات):
- اجعل طريقة إيصال الرمز (코드 전달 방식) هي SMS أو البريد الإلكتروني. ففي طريقة «صفحة الإدارة» (관리 화면) على المشغّل أن يبلّغ الرموز واحداً واحداً.
- أدخل قيم SMS أو البريد الإلكتروني (SMTP) (이메일 (SMTP)) واحفظها ← ثم تحقق بـالإرسال التجريبي (테스트 발송) من أنها تصل فعلاً.
- تأكد من أن أرقام الاختبار (테스트 번호) معطّلة. فإذا فُعّلت يستطيع أي شخص تسجيل الدخول بأرقام
+99966…. - وإن لزم الأمر، عطّل السماح بالتسجيلات الجديدة (새 가입 허용) عند البدء، واستقبل أولاً من تدعوهم فقط.
9. توصيل التطبيق بهذا الخادم
يُبنى التطبيق وعنوان IP الخادم ومنفذه ومفتاحه العام مضمّنة فيه. لذا يجب إعادة بنائه بالمفتاح العام لهذا الخادم كي يتصل به. على جهاز Mac:
# 1. المفتاح العام لهذا الخادم (العام لا الخاص — ويمكن تنزيله من موقع الوثائق)
curl -s -o keys/production.pem.pub https://pabal.me/docs/server-key.pem
# 2. توجيه شيفرة التطبيق إلى هذا الخادم + تطبيق العلامة التجارية
python3 scripts/tdesktop/point_to_server.py ~/Developer/tdesktop \
--host 203.0.113.10 --port 8443 --key keys/production.pem.pub
python3 scripts/tdesktop/apply_branding.py ~/Developer/tdesktop
بعد ذلك نفّذ الخطوتين 5 (configure) و6 (البناء) من docs/tdesktop-build-guide.md في المستودع. وانسخ الناتج out/Debug/Pabal.app باسم آخر — لأنك إذا أعدت بناء الشيفرة نفسها لخادم آخر فسيُستبدل.
البناء الحالي بناء تصحيح (debug) غير موقّع ولا مُصادَق عليه، لذا على من يستلمه أن يفتحه أول مرة بالنقر بالزر الأيمن ← فتح. ويحفظ بناء التصحيح بياناته في مجلد بجانب التطبيق (tdata/)، وإذا تعذّرت الكتابة هناك يستخدم مجلد البيانات نفسه الذي يستخدمه تطبيق Telegram Desktop الحقيقي. لذا أرشد المستخدمين إلى وضع التطبيق في مجلد المستخدم (مثل ~/Applications/Pabal/). أما بناء الإصدار للتوزيع العام (مجلد بيانات منفصل، وتوقيع Apple والمصادقة) فعمل منفصل.
التشغيل
الحالة والسجلات
cd /opt/pabal/deploy
docker compose ps
docker compose logs --since 1h pabal-server
tail -f /srv/pabal/pabal_server/logs/telegram-server.log
التحديث
cd /opt/pabal && git pull
cd deploy
./backup.sh # نسخة احتياطية أولاً
docker compose up -d --build pabal-server # استبدال الخادم وحده بالصورة الجديدة
docker compose logs --since 5m pabal-server | grep -E "Website|ERROR"
خلال عشرات الثواني التي يُعاد فيها تشغيل الخادم ينقطع التطبيق، ثم يعيد الاتصال بنفسه دون تسجيل دخول جديد. ويطبّق الخادم تغييرات الجداول تلقائياً عند التشغيل. والمجلدات المربوطة مستقلة عن الصورة، فلا تُحذف البيانات بـ docker compose down أو بحذف الصورة — فقط لا تحذف /srv/pabal.
النسخ الاحتياطي
./backup.sh # → /srv/pabal/backups/<التاريخ-الوقت>/{pabal.dump, server-keys-data.tar.gz}
crontab -e # يومياً في الساعة 03:00:
# 0 3 * * * /opt/pabal/deploy/backup.sh >> /srv/pabal/backups/backup.log 2>&1
- تُحذف تلقائياً النسخ الاحتياطية التي مضى عليها 14 يوماً (ويمكن تغيير ذلك، مثل
KEEP_DAYS=30 ./backup.sh). - انسخها إلى مكان آخر أيضاً. فالنسخة الاحتياطية على القرص نفسه لا تصمد أمام تعطّل القرص.
- تحتوي النسخ الاحتياطية على مفتاح RSA الخاص والقيم السرية لـ SMS وSMTP. فاحمِ مكان حفظها بقدر ما تحمي الخادم.
الاستعادة
cd /opt/pabal/deploy
B=/srv/pabal/backups/20260920-030000 # النسخة الاحتياطية المراد استعادتها
docker compose stop pabal-server pabal-caddy
docker compose exec -T pabal-postgres dropdb -U pabal pabal
docker compose exec -T pabal-postgres createdb -U pabal pabal
docker compose exec -T pabal-postgres pg_restore -U pabal -d pabal --no-owner < $B/pabal.dump
sudo tar -C /srv/pabal/pabal_server -xzf $B/server-keys-data.tar.gz
sudo chown -R 1000:1000 /srv/pabal/pabal_server
docker compose up -d
والأمر نفسه عند الانتقال إلى خادم جديد: نفّذ الخطوات من 1 إلى 5، ثم نفّذ الاستعادة أعلاه بدلاً من الخطوة 6، وشغّل. إذا استعدت المفتاح نفسه فلا حاجة إلى إعادة بناء التطبيق (إلا إذا تغيّر عنوان IP الخادم، فعندها أعد البناء).
التشغيل والإيقاف
docker compose restart pabal-server # إعادة تشغيل الخادم وحده
docker compose stop # إيقاف الكل (تبقى البيانات كما هي)
docker compose up -d # التشغيل من جديد
حتى لو أعدت تشغيل جهاز الخادم، تعمل الحاويات من جديد تلقائياً لأنها مضبوطة على restart: unless-stopped.
قائمة التحقق الأمني
- صلاحيات
.envهي 600، وPOSTGRES_PASSWORDقيمة عشوائية - صلاحيات
/srv/pabal/pabal_server/keysهي 700، ولا يوجد المفتاح الخاص في أي مكان آخر غير النسخ الاحتياطية - جدار الحماية: 22 (لعنوان IP المشغّل فقط إن أمكن) و80 و443 و8443 فقط
- من الخارج يعيد
https://النطاق/admin/الرمز 404 - صفحة الإدارة: أرقام الاختبار (테스트 번호) معطّلة، وطريقة إيصال الرمز (코드 전달 방식) هي SMS أو البريد الإلكتروني، والإرسال التجريبي (테스트 발송) ناجح
- لم تفعّل
TELEGRAM_WEBHOOK_ALLOW_LOCAL(كي لا تصل طلبات webhook الخاصة بالبوتات إلى الشبكة الداخلية) - SSH: عطّل تسجيل الدخول بكلمة المرور، واسمح بالمفاتيح فقط
- تحقق من مهمة cron للنسخ الاحتياطي ومن النسخ إلى مكان خارجي، وتدرّب على الاستعادة مرة واحدة
- التحديثات الأمنية التلقائية لنظام تشغيل الخادم (
unattended-upgrades)
حل المشكلات
| العَرَض | السبب ← الحل |
|---|---|
| التطبيق لا يتجاوز «جارٍ الاتصال…» | ① المنفذ 8443 محجوب ← nc -vz IP 8443، وتحقق من ufw ومن مجموعة الأمان السحابية ② بُني التطبيق بمفتاح عام آخر ← أعد الخطوة 9 بمفتاح هذا الخادم ③ قيمة PUBLIC_IP خاطئة ← صحّح .env ثم نفّذ docker compose up -d pabal-server |
| يتصل في البداية ثم ينقطع بعد قليل | ينتقل التطبيق إلى العنوان الذي أبلغه به الخادم (PUBLIC_IP:MTPROTO_PORT) لكن ذلك العنوان خاطئ ← تحقق من PUBLIC_IP |
| خطأ في شهادة HTTPS | DNS لا يشير بعد إلى هذا الخادم، أو المنفذ 80 محجوب ← dig +short النطاق، docker compose logs pabal-caddy |
server يعيد التشغيل باستمرار، مع password authentication failed | غيّرت POSTGRES_PASSWORD بعد إنشاء البيانات ← أعده إلى قيمته الأصلية، أو نفّذ داخل قاعدة البيانات ALTER USER pabal PASSWORD '…' |
AccessDeniedException: /app/keys/… | مالك المجلد المربوط ← sudo chown -R 1000:1000 /srv/pabal/pabal_server |
OutOfMemoryError، أو بطء | ارفع -Xmx في JAVA_OPTS ثم نفّذ docker compose up -d pabal-server |
| لا تصل رموز التسجيل | راجع حالة الإرسال وسبب الفشل في تبويب رموز التسجيل (가입 코드) في صفحة الإدارة ← ثم قيم SMS وSMTP في الإعدادات (설정)، والإرسال التجريبي (테스트 발송) |
| لا أستطيع الدخول إلى صفحة الإدارة | تحقق من أن نفق SSH يعمل، ومن أن برنامجاً آخر لا يستخدم المنفذ 8080 على حاسوبك (غيّره إلى -L 18080:127.0.0.1:8080 وافتح localhost:18080) |
network ssemiya-net declared as external, but could not be found | الشبكة غير موجودة بعد → docker network create ssemiya-net (أو اسم آخر عبر PABAL_NETWORK في .env) |
القيود المعروفة
- تكوين بخادم واحد. عند التشغيل تُحمَّل كل الحسابات والمحادثات والرسائل في الذاكرة. والتوسع الأفقي بتوزيعها على عدة خوادم غير ممكن بعد، فمع ازدياد البيانات يجب زيادة الذاكرة.
- رموز التسجيل المنتظرة وتحديثات البوتات التي لم تُجلب موجودة في الذاكرة، فتضيع عند إعادة تشغيل الخادم.
- لطلبات رموز التسجيل فاصل زمني وحد يومي، لكن لا يوجد بعد حد لمعدل سائر الطلبات. فراقب السجلات ولوحة المعلومات (대시보드) كثيراً بعد الإطلاق مباشرة.
- لا يوجد تطبيق للهاتف ولا إشعارات فورية. ومرفقات الرسائل مقتصرة على الصور. والقنوات والمجموعات الخارقة والتحقق بخطوتين غير متاحة بعد.
- مفاتيح المصادقة محفوظة في قاعدة البيانات نصاً صريحاً (يحتاج إليها الخادم لفك التشفير). فاحمِ قاعدة البيانات والنسخ الاحتياطية بقدر ما تحمي مفتاح RSA.
الملفات
| الملف | الدور |
|---|---|
deploy/docker-compose.yml | تكوين الإنتاج (pabal-server · pabal-postgres · pabal-caddy، مع ربط المجلدات) |
deploy/Caddyfile | HTTPS، وحجب مسارات الإدارة، وتمرير الموقع والوثائق وBot API |
deploy/.env.example | نموذج الإعدادات ← deploy/.env |
deploy/backup.sh | تفريغ قاعدة البيانات + أرشفة المفاتيح والبيانات، وتنظيف النسخ القديمة |
Dockerfile | صورة الخادم (البناء ← JRE 21، uid 1000) |