# التثبيت عبر Docker

المسار الأساسي هو `deploy/compose.sh`، ويفحص مدخلات المضيف قبل أي بناء أو سحب صور أو تشغيل عبر Compose. المرشح الأول Linux x86_64 مع Docker محلي بصلاحيات root وcgroup v2 والقدرات المطلوبة للموارد وrunc وseccomp الافتراضيين. تأتي Python وBun وأداة Docker CLI داخل صورة صباربيز؛ يحتاج المضيف POSIX shell وDocker/Compose وأدوات Linux العامة فقط. **اعتماد توافق المضيف والإنتاج غير مثبتين** حتى التثبيت النظيف وقياس الحدود وإعادة الإقلاع والاستعادة الكاملة فعلياً. راجع [عقد الفحص المسبق](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/HOST-PREFLIGHT.md) للمتطلبات والأسباب وحدود الأدلة.

اختر حجم الخادم أولًا من [اختيار خادم](https://base.sbarah.com/docs/guides/choosing-a-server/).

مجلد بيانات Docker الافتراضي هو `/var/lib/docker`، ومقبسه `/var/run/docker.sock`. إذا كانت خدمة Docker تستعمل مسارات مطلقة أخرى، فاضبط `SBARBASE_DOCKER_DATA_ROOT` على قيمة `DockerRootDir` التي تعلنها، و`SBARBASE_DOCKER_SOCKET` على مقبس Unix المحلي، قبل أن يفحص launcher وحدة التحكم وينشئها. هذان الإعدادان يختاران مسارات موجودة، ولا يعيدان ضبط Docker ولا ينقلان بياناته. يرفض الربط مصدرًا غير موجود بدل أن ينشئ مجلدًا فارغًا. وتفحص وحدة التحكم مجلد بيانات الخدمة، وهوية حاويتها الكاملة، ووسوم المشروع والخدمة، والربطين كليهما، قبل أي تعافٍ أو تجهيز.

تُفرَّغ `DOCKER_CONTEXT` و`DOCKER_TLS` و`DOCKER_TLS_VERIFY` داخل وحدة التحكم، فتستعمل أداتها المقبس المركّب. أما أمر Compose نفسه فيجب أن يستهدف خدمة Docker المحلية المقصودة. لم تجتز خدمات Docker البعيدة وDocker Desktop والتثبيت بلا root الاختبارات المطلوبة، ويرفضها profile `local-v1` صراحة. ويحتاج مجلد البيانات المخصص أيضًا طبقة تشغيل تعلن توافقها مع `local-v1`. والتراجع إلى طبقة تشغيل لا تعلن ذلك يبقى متوقفًا، بدل أن يستعمل بصمت مجلدها الافتراضي القديم.

## 1. تثبيت Docker

على Ubuntu 26.04:

```bash
sudo apt-get update && sudo apt-get install -y docker.io docker-compose-v2 docker-buildx git
sudo systemctl enable --now docker
```

هذه حزم التوزيعة نفسها. تُبنى صورة صباربيز عبر BuildKit، وتوفّره الحزمة `docker-buildx`. ثُبّتت هذه الحزم على آلة افتراضية فارغة بنظام Ubuntu 26.04، ونُفّذت عليها بقية خطوات هذه الصفحة ([دليل التجربة](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/evidence/vm-docker-install-checks.json)). يُتوقّع أن يعمل `moby-engine` على Fedora مع SELinux، وهذا ما يرفضه profile `local-v1` الحالي. لم يُتحقق من ذلك بعد، لذا فالمسار المجرَّب على Fedora هو [البدء السريع](https://base.sbarah.com/docs/guides/quickstart/).

## 2. جلب الشيفرة والتشغيل

```bash
sudo git clone https://github.com/M7MMAD-OMAR/sbarbase /opt/sbarbase
cd /opt/sbarbase && sudo deploy/compose.sh check && sudo deploy/compose.sh up
```

القيم الافتراضية تناسب تثبيت Docker العادي، فلا حاجة إلى تصدير أي شيء. اضبط مدخلات النشر قبل launcher فقط إن كانت مختلفة عندك. يختار ملف Compose من هذا المستودع والمقبس المحلي واسم المشروع، ولا يقرأ `.env`. المدخلات الأساسية هي `SBARBASE_ROOT` و`SBARBASE_DOCKER_SOCKET` و`SBARBASE_DOCKER_DATA_ROOT` واسم مشروع Compose ومنافذ الواجهة وقاعدة البيانات وعنوان الربط و`SBARBASE_PUBLIC_URL`. يجب أن يطابق `DOCKER_HOST` المقبس المعلن، وترفض إعدادات context/TLS/API وملفات أو profiles بديلة. `check` للقراءة فقط ولا ينشئ مسارات أو volumes أو حاويات أو يثبت حزماً. الأمر المباشر `docker compose up` يتجاوز فحص المضيف.

التشغيل الأول يبني صورة صباربيز ويسحب صور Supabase المثبّتة (نحو 2.4 GB)، ويستغرق بضع دقائق على اتصال سريع. تابعه بالأمر `sudo deploy/compose.sh logs`؛ يصبح جاهزًا عندما يظهر في السجل `Local Sbarbase API: http://127.0.0.1:8790`. ينتهي الأمر `up` قبل ذلك، فانتظر ظهور هذا السطر قبل الخطوة التالية؛ وقد يستغرق أكثر من 20 دقيقة على اتصال بطيء.

## 3. إنشاء أول مشغّل

```bash
cd /opt/sbarbase && sudo deploy/compose.sh bootstrap
```

يحافظ أمر bootstrap المحدد على المقبس ومسار المستودع واسم المشروع اللذين اختارهما launcher. يسأل عن بريد إلكتروني واسم عميل (مؤسسة) وكلمة مرور لا تظهر أثناء كتابتها. بعدها افتح الواجهة على `http://127.0.0.1:8790` على الخادم (مثلًا عبر `ssh -L 8790:127.0.0.1:8790 your-server`)، وسجّل الدخول، وأنشئ مشروعًا وبيئة، وانسخ بيانات الاتصال والمفتاح.

## 4. وضع HTTPS أمامه

الواجهة والـ API تستمعان على loopback فقط. انشرهما عبر وكيل TLS الموصوف في [نشر الخادم](https://base.sbarah.com/docs/guides/server-deployment/)، أو أي reverse proxy تستخدمه أصلًا، موجّهًا إلى `127.0.0.1:8790`.

إذا كان جدار الحماية على الخادم يُسقط الاتصالات الواردة افتراضيًا (كما يفعل ufw)، فاسمح بالمسارين من الحاويات إلى الخادم اللذين يحتاجهما Studio وEdge Functions ([النشر على خادم](https://base.sbarah.com/en/docs/guides/server-deployment/#firewall-two-routes-from-containers-to-the-host)).

## الإعدادات

يمرّر `deploy/compose.sh` قائمة ثابتة من الإعدادات إلى الحاوية، ويتجاهل `.env`. اكتبها في أمر launcher نفسه، لأن `sudo` يُسقط المتغيرات المصدَّرة:

```bash
cd /opt/sbarbase && sudo SBARBASE_PUBLIC_URL=https://api.example.com SBARBASE_STUDIO_HOST='studio-{id}.example.com' deploy/compose.sh up
```

- الإعداد `SBARBASE_PUBLIC_URL`: العنوان الذي يصل منه الناس ومزوّدو OAuth إلى هذا الخادم؛ ومنه يبني Auth روابط البريد وعناوين الرجوع.
- الإعداد `SBARBASE_STUDIO_HOST`: عنوان Studio العام لكل بيئة، و`{id}` مكان أحرفها الست عشرية الأربعة والعشرين. أعطِ وكيل TLS القيمة نفسها. يكتب `lab/studio_address.py apply` ملفات systemd إضافية، فهو لتثبيت systemd؛ أما `plan` و`verify` فيعملان هنا أيضًا ([Studio](https://base.sbarah.com/docs/guides/studio/)).
- وكذلك `SBARBASE_UPLOAD_LIMIT_MB` (50)، و`SBARBASE_MANAGEMENT_SESSION_SECONDS` (ثلاثون يومًا)، و`SBARBASE_DATABASE_PORT` (6543) و`SBARBASE_DATABASE_BIND` (`127.0.0.1`)، و`SBARBASE_BACKUP_HOUR` و`SBARBASE_BACKUP_KEEP`، وإعدادا التحديث أدناه.

كل إعداد منها مشروح في [الإعدادات](https://base.sbarah.com/docs/reference/configuration/). لا شيء يحفظها: أعطِ القيم نفسها في كل `deploy/compose.sh up`، ومنها الأمر الذي يلي `upgrade`، وإلا بدأت الحاوية المعاد إنشاؤها بالقيم الافتراضية. أما إعادة التشغيل من لوحة الإدارة أو عبر `restart: unless-stopped` فتحتفظ بها.

## أوامر يومية

| المهمة | الأمر |
|---|---|
| الحالة والسجلات | `deploy/compose.sh ps`، `deploy/compose.sh logs` |
| فحص السلامة | `deploy/compose.sh smoke` |
| إيقاف كل شيء بنظافة | `deploy/compose.sh down` |
| التشغيل من جديد | `deploy/compose.sh up` |
| تحديث صباربيز | صفحة التحديثات في لوحة الإدارة، أو قسم التحديثات أدناه |
| النسخ الاحتياطي والاستعادة | راجع [النسخ الاحتياطي والاستعادة](https://base.sbarah.com/docs/guides/backup-and-restore/)؛ النسخ اليومي يعمل وحده |

الإعداد `restart: unless-stopped` يعيد صباربيز بعد إعادة تشغيل الخادم، بشرط أن يبدأ Docker نفسه عند الإقلاع (باستخدام مدير الخدمات الخاص بتوزيعة المضيف). البيانات محفوظة في volumes الخاصة بـ Docker وفي المجلدين `.lab/` و`.secrets/` داخل نسخة المستودع، والأمر `deploy/compose.sh down` يحتفظ بها كلها.

## التحديثات

تعرض صفحة التحديثات في لوحة الإدارة الإصدار الموقّع الأحدث، وتثبّت الآمن منه بنقرة واحدة، وتثبّت الإصدار الذي يغيّر Auth أو Storage أو Realtime بعد أن تؤكد تحذيرًا ([الترقيات](https://base.sbarah.com/docs/guides/upgrades/)). ينتظر المشرف انتهاء العمل الجاري، ويأخذ نسخة احتياطية من كل بيئة، وينقل نسخة المستودع، ويتوقف بترتيب، ثم يخرج برمز 42. يعيد الإعداد `restart: unless-stopped` تشغيل الحاوية عند أي خروج وبالصورة نفسها. يبدأ سكربت الحاوية بفحص profile المثبت داخل الصورة قبل حارس الترقية، ويعيد الفحص بعده، ثم يحجز الإصدار الجديد حركة التطبيقات حتى يجتاز فحوص السلامة. وإن لم يجتزها عاد وحده، وأُعيد تشغيل الحاوية مرة أخرى على الإصدار السابق؛ ويعود الحارس أيضًا بعد 3 مرات تشغيل فاشلة، أو بعد تشغيل مات في منتصفه.

إعدادان في `compose.yaml` يخصّان التحديثات. يضبط `TZ` المنطقة الزمنية للحاوية، وبها تُقرأ نافذة الصيانة للتحديث التلقائي (UTC إن لم يُضبط؛ والصورة تحمل قاعدة بيانات المناطق الزمنية، فيعمل اسم مثل `Asia/Dubai`). ويوجّه `SBARBASE_RELEASE_SOURCE` فحص التحديثات إلى مرآة؛ اتركه فارغًا للمستودع الرسمي.

إعادة التشغيل العادية تستخدم الصورة نفسها والحاوية التي أنشأها `compose.yaml`. والإصدار الذي صنفه "يحتاج إعادة بناء" يغيّر أحدهما، فيُثبَّت على الخادم ثم يُعاد بناء الحاوية:

```bash
deploy/compose.sh upgrade vX.Y.Z
deploy/compose.sh up
```

لا تحدّث بالأمر `git pull`: فهو يتجاوز النسخة الاحتياطية ولقطة التحكم والعودة. والانتقال إلى أول إصدار فيه قناة التحديث يحتاج إعادة بناء أيضًا، وخطواته في [دليل الترقيات](https://base.sbarah.com/docs/guides/upgrades/). شُغّلت قناة التحديث في CI وفي آلة افتراضية محلية في 26 سبتمبر 2026، مع إصدارات موقّعة مؤقتة وتثبيت وتراجع عن إصدار معطوب ([دليل التجربة](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/evidence/vm-channel-checks.json)). يثبت ذلك نطاق التجربة فقط؛ ولم يُعتمد إصدار جديد من Supabase، ولم تُختبر القناة على خادم مستقل منشور للناس.

## كيف تتركب القطع

تحمل الحاوية طبقة التحكم: المشرف، وعامل التجهيز، والواجهة، والبوابة. وهي تشغّل خدمات Supabase المثبّتة كحاويات مجاورة عبر مقبس Docker على الخادم. أربعة إعدادات في `compose.yaml` تجعل ذلك يعمل، ويحافظ عليها اختبار:

- نسخة المستودع مركّبة على المسار نفسه كما على الخادم، والحاوية تستخدم شبكة الخادم، فالمسارات وعناوين loopback تعني الشيء نفسه داخلها وخارجها؛
- مجلد بيانات Docker المعلن مركّب للقراءة فقط، حتى تُطبَّق حدود القرص على القرص الذي يحمل بيانات Docker؛
- الإعداد `cgroup: host`، ليرى المتحكم هوية حاويته الكاملة ويفحصها بدقة؛
- الإعداد `init: true`، لأن المشرف يرفض أن يعمل كعملية رقم 1.

الوصول إلى مقبس Docker يعادل صلاحية root على الخادم، كما في التثبيت عبر systemd؛ [نموذج التهديدات](https://base.sbarah.com/docs/explain/threat-model/) يشرح لماذا يُقبل ذلك حاليًا.

يجهّز بدء الخدمة `.secrets` و`.secrets/upstream` بالصلاحية `0700` وملكية حساب الخدمة. تُرفض المجلدات الموجودة بملكية أو صلاحيات مختلفة والروابط الرمزية؛ راجع [إصلاح صلاحيات مجلد الأسرار](https://base.sbarah.com/en/docs/guides/server-deployment/#private-directory-permissions) قبل إعادة تشغيل نسخة قديمة مرفوضة.
