# الإعدادات

ما يستطيع المشغّل ضبطه، وأين يحفظ صباربيز حالته. المسارات نسبية إلى نسخة المستودع. لا يوجد في صباربيز ملف إعدادات واحد: الإعدادات موزعة على الملفات والخيارات أدناه، والباقي يحدده الكود وملفات القفل المثبّتة الإصدار.

## متطلبات الخادم

| الإعداد | مكانه | ملاحظات |
|---|---|---|
| عنوان Docker | `DOCKER_HOST`، أو `--docker-host` في `deploy/server-acceptance.sh` | يجب أن يصل إلى خدمة Docker أصلية على Linux. خدمة النظام لا ترث بيئة الطرفية، فإذا كان سياق Docker على الخادم يشير إلى مقبس نسخة سطح المكتب، فمرّره صراحة في ملف الوحدة |
| Bun | على `PATH`، و`--bun-dir` لوحدة الخدمة | يبني لوحة الإدارة ويشغّل خادم الحلقة المحلية |
| Python | `/usr/bin/python3`، الإصدار 3.12 أو أحدث، ومعه `cryptography` | الخيار `--python` في `deploy/server-acceptance.sh` يغيّره |

## الصور المثبّتة الإصدار

الملفات `lab/distro-image.lock.json` و`lab/images.lock.json` و`lab/storage-image.lock.json` و`lab/realtime-image.lock.json` و`lab/functions-image.lock.json` و`lab/studio-image.lock.json` تثبّت كل صورة من الأصل بوسمها وبصمتها. لا تغيّرها إلا عبر `lab/pin_update.py`، وانظر [الترقيات](https://base.sbarah.com/docs/guides/upgrades/).

## المثبّت والخدمة

أوامر `/usr/bin/python3 lab/install_server.py <command>`:

| الأمر أو الخيار | المعنى |
|---|---|
| `check` | فحص مسبق للقراءة فقط، وينتهي برمز غير الصفر عند أي عائق |
| `plan` | يطبع خطوات التثبيت بدقة |
| `install --bootstrap-file PATH` | يثبّت مستخدمًا ملف المشغّل ذا الصلاحية 0600 (أدناه) |
| `images` | يفحص إعدادات Docker، ثم يسحب كل صورة مثبّتة الإصدار ويتحقق منها |
| `smoke` | يتحقق من أن لوحة الإدارة ونقاط الإدارة تجيب |
| `supervise` | يولّد وحدة systemd لنسخة المستودع هذه ويتحقق منها، والخيار `--apply` يثبّتها (للجذر فقط)، و`--defer-start` يثبّتها ويفعّلها دون أن يشغّلها |
| `wait-console` | ينتظر حتى تجيب لوحة الإدارة؛ و`--timeout` يحدد الثواني، وكذلك مع `supervise --apply` |
| `--service-user`، `--home`، `--bun-dir` | الحساب ومجلد المنزل ومجلد Bun التي تُكتب في الوحدة. الحساب الافتراضي `sbarbase` |

يقبل `deploy/server-acceptance.sh` الخيارات `--rehearse` و`--skip-install` و`--install-unit` و`--first-project` و`--bootstrap-file` و`--service-user` و`--home` و`--bun-dir` و`--docker-host` و`--console-timeout` و`--python`. الوحدة المرفقة هي `deploy/sbarbase.service`. لا تعدّل نسخة مثبّتة منها يدويًا، بل ولّدها بالأمر `supervise`.

## وكيل TLS

ينهي `bun deploy/console-tls-proxy.ts` اتصالات HTTPS أمام خادم الحلقة المحلية.

| الخيار | الافتراضي | المعنى |
|---|---|---|
| `--cert`، `--key` | إلزامي | ملفا الشهادة والمفتاح |
| `--public-host` | إلزامي | اسم الخادم العام (والمنفذ اختياريًا). يُستخدم في إعادة التوجيه بدل ترويسة `Host` التي يرسلها العميل |
| `--https-port` | `8443` | منفذ استماع HTTPS |
| `--http-port` | `8080` | منفذ HTTP عادي يعيد التوجيه بالرمز `308` |
| `--upstream` | خادم الحلقة المحلية العامل | الوجهة التي تُمرَّر إليها الطلبات |
| `--max-body` | حد الرفع مع 1 MiB إضافي (51 MiB) | الأجسام الأكبر تأخذ `413`. الأجسام حتى 1 MiB تُقرأ كاملة، والأكبر منها (رفع الملفات) تُمرَّر كما تصل |
| `--studio-host` | `SBARBASE_STUDIO_HOST` | نمط عنوان Studio، مثل `studio-{id}.example.com`، ويخدم الوكيل عناوينه أيضًا. أي اسم خادم ليس الاسم العام ولا loopback ولا عنوان Studio مطابقًا يأخذ `421` |

يضبط الأمر `/usr/bin/python3 lab/studio_address.py plan|apply|verify DOMAIN` العنوان العام لـStudio مرة واحدة: `plan` يعدّد سجل DNS الشامل والشهادة والإعداد المطلوب توفيرها، و`apply` (بصلاحية الجذر) يكتب `SBARBASE_STUDIO_HOST` في ملف systemd إضافي (drop-in) للوحة الإدارة (`--service`، وافتراضيه `sbarbase`) وللوكيل (`--proxy-service`، وافتراضيه `sbarbase-proxy`) ثم يعيد تشغيلهما، و`verify` يخبرك بالخطوة الناقصة ([Studio](https://base.sbarah.com/en/docs/guides/studio/#open-it-from-anywhere)).

## ملف الإعداد الأولي للمشغّل

يسأل `/usr/bin/python3 lab/operator_file.py PATH` عن البيانات دون إظهار ما تكتبه، ثم يكتب ملف JSON بصلاحية 0600 فيه `email` و`password` و`organization` فقط. الخيار `--stdin` يقرأ الكائن نفسه من الإدخال القياسي (بحد أقصى 8192 بايت) للأتمتة. مرّر الملف إلى `install --bootstrap-file`، أو شغّل `lab/bootstrap.py` تفاعليًا بدلًا منه. انظر [إعداد المشغّل](https://base.sbarah.com/docs/guides/operator-setup/).

## بريد كل بيئة

يُفعَّل بريد التطبيق (التأكيد والاستعادة) لبيئة واحدة بملف واحد هو `.secrets/upstream/<runtime>-mail.json` بصلاحية 0600. اكتبه أو اعرضه أو احذفه بالأمر `lab/mail_config.py write|show|remove PATH`، ولا تُطبع كلمة المرور أبدًا. المفاتيح: `host` و`port` و`user` و`pass` و`admin_email` و`sender_name` و`reply_to` و`max_frequency` و`otp_exp` و`otp_length` و`secure_email_change` و`autoconfirm`. يسري التغيير بمطابقة حاوية Auth لتلك البيئة. المخطط الكامل: [بريد البيئة](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/ENVIRONMENT-EMAIL.md).

## تنبيهات المشغّل

إذا وُجد الملف `.lab/upstream/notifications.json`، يرسل العامل أحداث المشغّل بالبريد، أو بخطاف ويب موقّع، أو عبر تيليجرام، أو بأي مزيج منها:

```json
{
  "schema": 1,
  "email": {"enabled": true, "host": "smtp.example.invalid", "port": 587,
            "from": "sbarbase@example.invalid", "to": "operator@example.invalid", "tls": "starttls"},
  "webhook": {"enabled": true, "url": "https://hooks.example.invalid/sbarbase",
              "secretFile": ".secrets/upstream/notifier.json"},
  "telegram": {"enabled": true, "chatId": "-1001234567890",
               "tokenFile": ".secrets/upstream/telegram.json"}
}
```

قيمة `tls` واحدة من `none` أو `starttls` أو `tls`. سر توقيع خطاف الويب محفوظ في `.secrets/upstream/notifier.json` بالشكل `{"schema": 1, "webhookSecret": "<64 hex characters>"}`. لتيليجرام: أنشئ بوتًا عبر @BotFather، وأضفه إلى محادثتك، وضع رمزه في ملف خاص (صلاحياته 0600) بالشكل `{"schema": 1, "botToken": "<token>"}`. قيمة `chatId` هي رقم المحادثة، أو `@channelname` لقناة عامة. يُقرأ الرمز من هذا الملف فقط، ولا يظهر في أي رسالة. التصميم الكامل: [تنبيهات المشغّل](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/OPERATOR-NOTIFICATIONS.md).

**ربط تيليجرام من لوحة الإدارة.** يستطيع مالك التثبيت ربط تيليجرام دون تعديل أي ملف: من **التنبيهات** في قائمة التثبيت. الصق رمز البوت الذي أخذته من @BotFather، فيتحقق منه صباربيز مع تيليجرام، ويحفظه في `.secrets/upstream/telegram.json` (صلاحياته 0600)، ولا يعرضه بعدها أبدًا، بل آخر أربعة أحرف منه فقط. ثم افتح الرابط الذي تعطيك إياه الصفحة واضغط **Start** في تيليجرام: لا تُربط إلا المحادثة التي تفتح هذا الرابط، وهو يعمل مرة واحدة ويبقى صالحًا 30 دقيقة، وتصلها رسالة تأكيد. ومن الصفحة نفسها ترسل رسالة تجريبية، أو تفصل القناة فينسى صباربيز الرمز. تبقى القنوات الأخرى في `notifications.json` كما هي، ويسري أي تغيير على التثبيت العامل خلال ثانية دون إعادة تشغيل. يرى مدراء التثبيت حالة القناة، ولا يغيّرها إلا المالكون، ويُسجَّل كل تغيير في سجل التدقيق. إذا انكشف الرمز يومًا، أرسل `/revoke` إلى @BotFather والصق الرمز الجديد.

**امتلاء القرص وتوقف الخدمات.** يفحص المشرف مرة كل دقيقة. إذا قلّ المتاح في نظام ملفات يكتب فيه (مجلد التثبيت، ومجلد بيانات Docker) عن 10% أو 5 غيغابايت يصلك تحذير، وإذا قلّ عن 5% أو 2 غيغابايت يصلك تنبيه حرج. وإذا بقيت حاوية قاعدة البيانات أو Storage أو تسجيل دخول الإدارة، أو حاوية Auth أو REST أو Realtime لإحدى البيئات، متوقفة خمس دقائق يصلك تنبيه حرج. لا تُراقب Edge Functions، لأنها تبقى متوقفة عمدًا ما دامت البيئة موقوفة عن الكتابة.

**الفحص من الخارج.** الخادم المتوقف لا يستطيع أن يبلّغ عن نفسه. في `deploy/uptime-worker/` عامل Cloudflare (Worker) يسأل مسار `/health` العام كل خمس دقائق: فشلان متتاليان يرسلان رسالة واحدة على تيليجرام، وأول جواب سليم بعدها يرسل رسالة أخرى. انسخ هناك `wrangler.example.toml` إلى `wrangler.toml` (يتجاهله git)، واضبط فيه `HEALTH_URL` ومعرّف مساحة KV لحفظ حالته (`bunx wrangler kv namespace create sbarbase-uptime`)، ثم انشره بالأمر `bunx wrangler deploy -c deploy/uptime-worker/wrangler.toml`، وأعطه رمز البوت ورقم المحادثة سرّين بالأمرين `bunx wrangler secret put TELEGRAM_TOKEN` و`bunx wrangler secret put CHAT_ID` (مع `-c` نفسه)؛ لا يُكتب أيّ منهما في ملف. رقم المحادثة هو `chatId` الذي كتبته لوحة الإدارة في `.lab/upstream/notifications.json`.

من بين الأحداث: **بيئة ظلت تحتاج أكثر من حصتها.** تضمن البوابة لكل بيئة 8 طلبات في الوقت نفسه، وتسمح للمزدحمة أن تستعير حتى 24 من 64 (8 لكل واحدة من البيئات الثماني التي يتسع لها التثبيت)، مع إبقاء الحصة غير المستخدمة لكل مشروع نشط في الدقيقة الأخيرة فارغة (8 على الأقل). الاستعارة وحدها لا تُبلَّغ أبدًا. إذا بقيت البيئة 15 دقيقة متتالية تُرفض عند حدها، أو تزاحم جارة لها، يصلك تنبيه واحد عنها مع ما يجب فعله: ارفع حصتها (صفحة البيئة في لوحة الإدارة، قسم **حصة البوابة**، لمشغّلي التثبيت وحدهم)، أو انقلها إلى محرك قاعدة بيانات خاص بها، أو كبّر الخادم. لا تُرفع الحصة إلا إذا بقيت حصص كل البيئات الجاهزة ضمن الـ64 التي تملكها البوابة، فإن لم تتسع فاخفض حصة بيئة أخرى أولًا. التصميم: [الحصة العادلة](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/FAIR-SHARE-ADMISSION.md).

## نسخ احتياطية خارج الخادم

إذا وُجد الملف `.lab/upstream/backup-offsite.json` يُشفَّر كل تشغيل يومي للنسخ الاحتياطي ويُنسخ إلى مخزن واحد متوافق مع S3 (bucket):

```json
{
  "schema": 1,
  "s3": {"endpoint": "https://s3.eu-central-1.amazonaws.com", "region": "eu-central-1",
         "bucket": "example-backups", "prefix": "sbarbase/",
         "credentialsFile": ".secrets/upstream/offsite-s3.json"},
  "keyFile": ".secrets/upstream/offsite-key.json"
}
```

يجب أن يكون `endpoint` بعنوان `https` (ويُقبل `http` العادي على الحلقة المحلية فقط). تقبل `prefix` الحروف والأرقام و`.` و`_` و`-` و`/`. الحقل `credentialsFile` ملف بصلاحية 0600 بالشكل `{"schema": 1, "accessKeyId": "...", "secretAccessKey": "..."}`. والحقل `keyFile` ملف بصلاحية 0600 بالشكل `{"schema": 1, "key": "<64 hex characters>"}`، لا يُنشأ إلا بطلب صريح عبر `python3 lab/backup.py offsite-key PATH`. يُرفض الملفان إذا كانا رابطًا رمزيًا أو مقروءين للمجموعة أو لغيرها. يتبع الاحتفاظ `SBARBASE_BACKUP_KEEP`. الإعداد والحدود في [النسخ الاحتياطي والاستعادة](https://base.sbarah.com/docs/guides/backup-and-restore/).

## قناة التحديث

تقع إعدادات التحديث وطلباته وسجل الترقية في `.lab/upgrades/`، خاصة بحساب الخدمة: المجلد 0700، وملفات JSON بصلاحية 0600، ويُستبدل كل منها دفعة واحدة. لا تكتب لوحة الإدارة إلا `settings.json` و`request.json`، ويكتب المشرف و`lab/upgrade.py` الباقي ([الترقيات](https://base.sbarah.com/docs/guides/upgrades/)).

| المسار | ما يحفظه |
|---|---|
| `.lab/upgrades/settings.json` | إعدادات المشغّل: `check` (مفعّل افتراضيًا)، و`automatic` (معطّل افتراضيًا)، و`window` نافذة الصيانة بالتوقيت المحلي للخادم (افتراضيًا من 3:00 AM إلى 5:00 AM، وتُحفظ `"03:00"` و`"05:00"`). الملف الغائب أو التالف يعني القيم الافتراضية |
| `.lab/upgrades/request.json` | الطلب الوحيد قيد التنفيذ (`apply` أو `rollback` أو `check`، مع `acknowledged` لإصدار `attended`)، ولا يُنشأ إلا إذا لم يوجد غيره؛ ويحكم عليه المشرف من جديد قبل التنفيذ |
| `.lab/upgrades/last-request.json` | آخر طلب انتهى، لعرض التقدم في لوحة الإدارة |
| `.lab/upgrades/current.json` | كلمة المشرف إلى لوحة الإدارة: الإصدار الذي يعمل، وحكم `rollback`، وحكم `apply` على الإصدار المعروض (هل يمكن تثبيته الآن، والسبب، وهل يحتاج الإقرار)، و`pending` ما دامت ترقية أو تراجع ينتظر، و`timezone` التي تُقرأ بها النافذة |
| `.lab/upgrades/available.json` | نتيجة آخر فحص: الإصدار الذي يعمل، والإصدار المعروض بصنفه وملاحظاته وأسباب رفضه، والإصدارات الأحدث التي تخطّاها الفحص مع السبب |
| `.lab/upgrades/available.previous.json` | نتيجة فحص جرى على إصدار آخر، نُقلت جانبًا حتى لا تعرض لوحة الإدارة الإصدار الذي ثُبّت للتو |
| `.lab/upgrades/check.json` | وقت آخر فحص، وخطؤه، وعدد مرات الفشل المتتالية (لتباعد المحاولات) |
| `.lab/upgrades/outcome.json` | كيف انتهت آخر عملية تحديث فرعية شغّلها المشرف (هل تجاوزت نقطة اللاعودة، وهل غيّرت شيئًا، وأسباب الرفض، والخطأ)، لتفاصيل الطلب وللمحاولات التلقائية |
| `.lab/upgrades/ledger.json` | لكل إصدار: هل أُعلن عنه، وعدد المحاولات التلقائية، وهل استُنفدت محاولة بعد نقطة اللاعودة، وهل تُراجع عنه |
| `.lab/upgrades/state.json` | آخر ترقية: من أين وإلى أين، والمرحلة (`applied`، `confirmed`، `rolling_back`، `rolled_back`، `rollback_failed`، `failed`)، ومن بدأها، ولقطتها، وعدد محاولات الحارس ومرات فشل النقل، وسبب العودة، وفشل التراجع عن إصدار معتمد، وهل هي عالقة، والإشعارات التي يرسلها التشغيل التالي |
| `.lab/upgrades/snapshots/` | لقطات حالة التحكم (الفهرس ومخزن المفاتيح) مع ملف وصف؛ تُحفظ أحدث ثلاث، ومعها اللقطة التي تذكرها آخر ترقية |
| `.lab/upgrades/guard.py` | حارس التشغيل الخاص بالإصدار الذي غادرته آخر ترقية، ويشغّله كل تشغيل أولًا (انظر [حارس التشغيل](https://base.sbarah.com/en/docs/guides/upgrades/#the-start-guard)) |
| `.lab/upgrades/hold` | موجود ما دام إصدار جديد ينتظر فحوص السلامة؛ ولا تحجز البوابة حركة التطبيقات إلا إذا قال `state.json` أيضًا إن بداية ما تنتظر الاعتماد |
| `.lab/upgrades/probe-token` | رمز عشوائي لفحوص سلامة هذا التشغيل عبر البوابة، بصلاحية 0600؛ ولا يوجد إلا ما دام الحجز قائمًا |
| `.lab/upgrades/evidence-<time>/` | أدلة كُتبت على هذا الخادم، نُسخت جانبًا قبل أن تنتقل نسخة المستودع (في ترقية أو عودة) |
| `.lab/upgrades/aside-<time>/` | التعديلات المحلية على الملفات المتتبَّعة خارج `docs/evidence/`، والملفات غير المتتبَّعة التي سيكتب الإصدار السابق فوقها، تنسخها العودة إلى هنا قبل أن تنقل نسخة المستودع قسرًا؛ مجلد لكل عودة. لا شيء يحذفها: احذف المجلد بنفسك حين لا تحتاجه |
| `.lab/upgrades/upgrade.lock`، `channel.lock`، `check.log`، `apply.log`، `rollback.log` | القفل الذي تحمله ترقية أو تراجع واحد، وقفل فحص أو جلب إصدار واحد، ومخرجات آخر عملية فرعية من كل نوع |
| `.lab/upstream/worker-drain` | موجود ما دام المشرف يصرّف العمل قبل تحديث: لا يلتقط العامل مهمة جديدة |
| `.lab/upstream/upgrade-intent.json` | الصور المثبّتة التي يجوز للتشغيل التالي أن يستبدلها، وتكتبه الترقية أو العودة |

يحدد `SBARBASE_RELEASE_SOURCE` مستودع Git الذي يقرأه فحص الإصدارات (عنوان أو مسار)، والافتراضي المستودع الرسمي عبر HTTPS. أيًا كان المصدر، يُتحقق من التواقيع مقابل `deploy/release-signers` في نسخة المستودع التي تعمل. ويضبط `TZ` المنطقة الزمنية التي تُقرأ بها نافذة الصيانة؛ ويمرر `compose.yaml` كليهما إلى الحاوية (انظر [إعدادات المشغّل](https://base.sbarah.com/en/docs/reference/configuration/#operator-settings)).

## مجلدات الحالة

يتجاهل Git المجلدين كليهما. لا تطبع محتوى `.secrets/` أبدًا، ولا تحذف أيًّا منهما لتتجاوز رفضًا.

| المسار | ما يحفظه |
|---|---|
| `.lab/upstream/control.sqlite` | الفهرس: العملاء والمشاريع والبيئات والعضويات والمهام والتوجيه |
| `.lab/upstream/server.json` | عنوان خادم الحلقة المحلية العامل ورقم عمليته (PID) |
| `.lab/upstream/*.json` | سجلات العمليات وواصفات الاستعادة ومخرجات الفحوص الحية |
| `.lab/ui/` | لوحة الإدارة بعد بنائها |
| `.lab/backups/` | النسخ اليومية لكل بيئة، وبيان التثبيت لكل تشغيل تحت `installation/` |
| `.lab/backups/upgrade-moved.json` | تشغيلات النسخ الاحتياطي الخاصة بترقيات نقلت نسخة المستودع. تُحمى آخر 3 منها من الحذف الدوري؛ أما محاولة الترقية التي توقفت قبل الانتقال فنسخها عادية |
| `.secrets/upstream/runtime.json` | بيانات الاعتماد المولّدة للخدمات التي يملكها صباربيز |
| `.secrets/upstream/managed-keys.sqlite` | البيانات الوصفية لمفاتيح API: المفاتيح السرية ببصماتها فقط، والمفاتيح العامة محفوظة أيضًا لتعرضها اللوحة مرة أخرى |
| `.secrets/upstream/access-tokens.sqlite` | رموز الوصول (`sbp_...`) ببصمات SHA-256، مع نطاقها وتاريخ انتهائها |
| `.secrets/upstream/studio-session.key` | المفتاح الذي يوقّع تذاكر دخول Studio وملفات تعريف جلسته |
| `.secrets/upstream/telegram.json` | رمز بوت Telegram، عند ربطه من لوحة الإدارة |
| `.secrets/upstream/bootstrap.json` | سجل عملية إعداد المشغّل (بلا كلمة مرور) |
| `.secrets/offsite.json` | إعدادات النسخ خارج الخادم، ومفتاح التخزين وعبارة المرور ([النسخ الاحتياطي والاستعادة](https://base.sbarah.com/docs/guides/backup-and-restore/#نسخ-خارج-الخادم)) |
| `.secrets/upstream/<runtime>-auth.json` | إعدادات تسجيل الدخول لبيئة، ومنها أسرار المزوّدين، تكتبها اللوحة ([تسجيل الدخول](https://base.sbarah.com/docs/guides/sign-in/)) |

## إعدادات المشغّل

اضبطها في `compose.yaml` (مع Docker) أو في أسطر `Environment=` لخدمة systemd.

| المتغير | الافتراضي | المعنى |
|---|---|---|
| `SBARBASE_STUDIO_HOST` | `{id}.studio.localhost` | عنوان Studio لكل بيئة، و`{id}` مكان أحرفها الست عشرية الأربعة والعشرين، مثل `studio-{id}.example.com`. القيمة الافتراضية تعمل عبر نفق SSH، أما النمط العام فيحتاج سجل DNS شاملًا وشهادة تغطيه، ويقرأ وكيل TLS المتغير نفسه (يكتبه `lab/studio_address.py` للاثنين؛ [Studio](https://base.sbarah.com/docs/guides/studio/#فتحه-من-أي-مكان)). يُطبَّق أي تغيير عند التشغيل التالي |
| `SBARBASE_PUBLIC_URL` | `http://localhost` | العنوان الذي يصل منه الناس ومزوّدو OAuth إلى هذا الخادم، مثل `https://api.example.com`. يبني Auth منه روابط البريد وعناوين العودة من OAuth. يُطبَّق أي تغيير عند التشغيل التالي |
| `SBARBASE_CONSOLE_PORT` | يُختار عند التشغيل، و`8790` مع Docker | منفذ اللوحة والـ API على الحلقة المحلية، لوكيل TLS |
| `SBARBASE_BACKUP_HOUR` | `3` | ساعة النسخ الاحتياطي اليومي بتوقيت UTC؛ القيمة `off` توقفه |
| `SBARBASE_MANAGEMENT_SESSION_SECONDS` | `2592000` | عدد الثواني التي يجوز فيها لتسجيل دخول واحد بكلمة المرور إبقاء جلسة الإدارة صالحة، من 3600 إلى 2592000 (ثلاثون يومًا). القيمة الفارغة أو غير الصالحة أو الخارجة عن النطاق تعني الافتراضي، لا أقرب حد. يلزم بعد التغيير إعادة تشغيل الخدمة: يقطع الخفض الجلسات القائمة عند طلبها التالي، ويسري الرفع على الإثباتات التي تصدر بعد ذلك. تحفظ لوحة الإدارة الجلسة في المتصفح حتى تسجيل الخروج، ويقرؤها أي برنامج نصي يعمل على نطاقها ([التفاصيل وطريقة الضبط، في المصادقة متعددة العوامل لحسابات الإدارة](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/MANAGEMENT-MFA.ar.md)) |
| `SBARBASE_BACKUP_KEEP` | `7` | عدد النسخ المحفوظة لكل بيئة. لا تُحسب النسخ المأخوذة لترقية: تُحفظ نسخ آخر 3 ترقيات نقلت نسخة المستودع دائمًا |
| `TZ` | UTC في الحاوية | المنطقة الزمنية التي تُقرأ بها نافذة الصيانة للتحديث التلقائي، مثل `Asia/Dubai`. خارج Docker تسري منطقة الخادم نفسه |
| `SBARBASE_RELEASE_SOURCE` | المستودع الرسمي | المكان الذي يقرأ منه فحص التحديثات الإصدارات الموقّعة: عنوان Git لمرآة أو مسارها |
| `SBARBASE_DATABASE_PORT` | `6543` | منفذ الوصول المباشر إلى قاعدة البيانات ([الوصول إلى قاعدة البيانات](https://base.sbarah.com/docs/guides/database-access/))؛ والقيمة `off` تطفئه |
| `SBARBASE_DATABASE_BIND` | `127.0.0.1` | العنوان الذي يستمع عليه ذلك المنفذ. أبقِه على loopback واستخدم نفق SSH؛ فأي عنوان آخر يرسل بيانات قاعدة البيانات دون تشفير |
| `SBARBASE_UPLOAD_LIMIT_MB` | `50` | أكبر ملف يستطيع التطبيق رفعه إلى Storage، بالميبيبايت (من 1 إلى 5120)، مثل حد حجم الملفات العام في Supabase. الرفع الأكبر يأخذ `413`. يُطبَّق أي تغيير عند التشغيل التالي، الذي يعيد إنشاء حاوية Storage المشتركة؛ ويمكن أن يكون حد الـbucket نفسه أصغر ([الدليل](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/evidence/docker-upload-checks.json)) |

ومع Docker يقرأ `deploy/compose.sh` هذه أيضًا. ويرفض إن غاب المقبس أو مجلد بيانات Docker، أو إن لم يكن `SBARBASE_ROOT` هو نسخة المستودع هذه:

| المتغير | الافتراضي | المعنى |
|---|---|---|
| `SBARBASE_ROOT` | نسخة المستودع | نسخة المستودع، مركّبة في المسار نفسه داخل الحاوية، ويجب أن تكون النسخة التي يعمل منها `deploy/compose.sh` |
| `SBARBASE_DOCKER_SOCKET` | `/var/run/docker.sock` | مقبس Docker المحلي الذي تتحكم به الحاوية |
| `SBARBASE_DOCKER_DATA_ROOT` | `/var/lib/docker` | مجلد بيانات Docker، مركّبًا للقراءة فقط لتجد حدود الإدخال والإخراج قرصه |
| `SBARBASE_COMPOSE_PROJECT` | `COMPOSE_PROJECT_NAME`، وإلا `sbarbase` | اسم مشروع Compose |

## متغيرات البيئة الداخلية

باقي المتغيرات التي تبدأ بـ`SBARBASE_*` (مثل `SBARBASE_WORKER_FD` و`SBARBASE_EFFECT_TOKEN`، و`SBARBASE_DOCKER_PROFILE` و`SBARBASE_CONTAINER` اللذين يضبطهما `compose.yaml`) تنقل واصفات الأقفال والرموز بين عمليات صباربيز نفسها. ليست إعدادات للمشغّل، فلا تضبطها يدويًا.

## ما لا يمكن ضبطه بعد

فئات الموارد وعتبات القبول ثابتة في الكود ([lab/resource_policy.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/resource_policy.py)، [lab/pressure_admission.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/pressure_admission.py)). حدود التزامن في البوابة ومهلها قيم افتراضية في المُنشئ داخل [src/gateway/concurrency.ts](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/src/gateway/concurrency.ts).
