> For the complete documentation index, see [llms.txt](https://ayakaleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayakaleaf-pro.ayaka.space/on-premises/ar/alsyanh/horizontal-scaling.md).

# التوسّع الأفقي

بدءًا من الإصدار 3.5.6، يدعم Server Pro التوسّع الأفقي.

تسرد هذه الوثيقة المتطلبات التقنية وتقدّم إرشادات لتشغيل Server Pro على أكثر من عقدة واحدة.

{% hint style="danger" %}
بدءًا من Server CE/Server Pro `5.0.3` تمت إعادة تسمية متغيرات البيئة من `SHARELATEX_*` إلى `OVERLEAF_*`.

إذا كنت تستخدم `4.x` الإصدار (أو أقدم)، فيرجى التأكد من أن المتغيرات تحمل السابقة المناسبة (مثلًا `SHARELATEX_SITE_URL` بدلاً من `OVERLEAF_SITE_URL`)
{% endhint %}

إعداد التوسّع الأفقي يتطلب قدرًا كبيرًا من الجهد. ننصح بالنظر في التوسّع الأفقي **فقط** عند الوصول إلى نطاق معيّن. على سبيل المثال، تم إعداد تثبيت Server Pro لـ 1,000 مستخدم إجمالي بنجاح باستخدام خادم واحد مزوّد بمعالجين رباعيي النوى وذاكرة نظام 32 جيجابايت. راجع [متطلبات العتاد](/on-premises/ar/albda/requirements/hardware-requirements.md) في الوثائق للحصول على التوصيات.

يتضمن نشر Server Pro مع التوسّع الأفقي مجموعة من المكونات الخارجية، مثل موازن تحميل وواجهة تخزين خلفية متوافقة مع S3.

يمكننا المساعدة في استكشاف الأخطاء وإصلاحها داخل حاويات Server Pro التي قد تكون ناتجة عن سوء تهيئة، وتقديم نصائح عامة استنادًا إلى هذه الوثيقة. للأسف، لا يمكننا تقديم المساعدة في تهيئة تطبيقات/أنظمة الجهات الخارجية.

حل المشكلات التقنية الخاصة بالعتاد/البرمجيات لديك لتوفير المكونات الخارجية غير مشمول بشروط الدعم لدينا.

### المتطلبات

#### تخزين بيانات خارجي ومركزي

يمكن تقسيم تخزين البيانات في Server Pro إلى أربعة مخازن بيانات:

* **MongoDB**

  * يتم تخزين معظم البيانات بشكل دائم في MongoDB.
  * ندعم إما مثيلًا محليًا أو مثيلًا خارجيًا، مثل [MongoDB](https://www.mongodb.com/atlas) Atlas (خدمة MongoDB مُدارة بالكامل تعمل ضمن بنية AWS التحتية).<br>

  **ملاحظة:** للأسف، لا يوجد دعم رسمي حاليًا لقواعد بيانات متوافقة مع MongoDB مثل CosmoDB/DocumentDB، لأننا لم نختبر Server Pro معها. وعلى الرغم من أن نشر Server Pro مع قواعد بيانات متوافقة **قد** يكون ممكنًا، فإننا ندعم رسميًا فقط عمليات النشر باستخدام MongoDB.<br>
* **Redis**

  * يخزن Redis البيانات المؤقتة، مثل تحديثات المستندات المعلّقة قبل تفريغها إلى MongoDB.
  * يُستخدم Redis للتواصل بشأن تحديثات المستندات بين الخدمات المختلفة وإشعار المحرر بتغييرات الحالة في مشروع معيّن.
  * يُستخدم Redis لتخزين جلسات المستخدمين.
  * ندعم إما مثيلًا محليًا أو مثيلًا خارجيًا.<br>

  **ملاحظة:** للأسف، لا يوجد دعم رسمي حاليًا لمخازن المفاتيح/القيم المتوافقة مع Redis مثل KeyDB/Valkey، لأننا لم نختبر Server Pro معها. وعلى الرغم من أن نشر Server Pro مع مخازن متوافقة **قد** قد يكون ممكنًا، فإننا ندعم رسميًا فقط عمليات النشر باستخدام Redis.<br>
* **ملفات المشروع وملفات السجل**

  * تُخزن ملفات المشروع غير القابلة للتحرير خارج MongoDB.

    كما يخزن نظام سجل المشروع الجديد (بدءًا من Server Pro 3.5) السجل خارج MongoDB أيضًا.
  * بالنسبة للمثيلات الفردية الصغيرة، ندعم إما نظام ملفات محليًا (يمكن أن يستند إلى SSD محلي أو NFS أو EBS) أو [نظام تخزين بيانات متوافق مع S3](/on-premises/ar/althyeh/overleaf-toolkit/s3.md).
  * بالنسبة للتوسّع الأفقي، نحن **فقط** ندعم أنظمة تخزين بيانات متوافقة مع S3.<br>

  **مهم:** NFS/Amazon EFS/Amazon EBS **لا** مدعومة للتوسّع الأفقي. يُرجى الاطلاع على [تخزين العتاد](/on-premises/ar/albda/requirements/hardware-requirements.md#storage) قسم المتطلبات الخاص بتوسيع التخزين في Server Pro لمزيد من التفاصيل.
* **الملفات المؤقتة**
  * يجب أن تُشغَّل عمليات تجميع LaTeX على أقراص محلية سريعة للحصول على الأداء الأمثل. لا حاجة للاحتفاظ بمخرجات التجميع بشكل دائم أو نسخها احتياطيًا.
  * كما تستفيد عملية تخزين عمليات رفع الملفات الجديدة مؤقتًا وإنشاء ملفات zip الخاصة بالمشروع من استخدام قرص محلي.

{% hint style="danger" %}
ننصح بشدة باستخدام قرص محلي. قد يؤدي استخدام أي نوع من الأقراص الشبكية (مثل NFS أو EBS) إلى أخطاء تجميع غير متوقعة ومشكلات أداء أخرى.
{% endhint %}

#### **Git-bridge**

{% hint style="info" %}
أصبح Git-bridge متاحًا في Server Pro بدءًا من الإصدار 4.0.1.
{% endhint %}

تُخزن مستودعات git محليًا على القرص. لا تتوفر خيارات نسخ متماثل. يجب تشغيل Git-bridge كـ **مثيل منفرد**. للحصول على الأداء الأمثل، ننصح باستخدام قرص محلي لبيانات git-bridge. يجب نسخ قرص بيانات git-bridge احتياطيًا بانتظام.

لتخزين البيانات مع التوسّع الأفقي، تحتاج إلى:

* مثيل MongoDB مركزي يمكن الوصول إليه من جميع مثيلات Server Pro
* مثيل Redis مركزي يمكن الوصول إليه من جميع مثيلات Server Pro
* واجهة تخزين خلفية مركزية متوافقة مع S3 لملفات المشروع والسجل
* قرص محلي على كل مثيل للملفات المؤقتة
* قرص محلي على المثيل الذي يستضيف حاوية git-bridge لبيانات git-bridge

#### متطلبات موازن التحميل

* **التوجيه المستمر**، مثلًا باستخدام ملف تعريف ارتباط

  ينبع هذا المتطلب من هذه المكونات:

  * تستخدم ميزة التحرير الفوري في Server Pro بروتوكول WebSockets مع الرجوع إلى استطلاع XHR عند الحاجة. لكل جلسة تحرير حالة محلية على جانب الخادم، ويجب دائمًا توجيه طلبات جلسة تحرير معيّنة إلى نفس مثيل Server Pro. وتستخدم ميزة التعاون Redis [النشر/الاشتراك](https://redis.io/docs/latest/develop/interact/pubsub/) لمشاركة التحديثات بين عدة مثيلات Server Pro.
  * يحتفظ تجميع LaTeX بالمخرجات وذاكرة التخزين المؤقت للتجميع محليًا للحصول على أداء اختياري. عند إرسال طلب تجميع إلى أحد مثيلات Server Pro، يجب توجيه طلبات تنزيل PDF/السجل التالية إلى نفس المثيل.
* **مهلات طلبات طويلة** لدعم تجميع مستندات LaTeX الكبيرة
* **دعم WebSocket** للحصول على الأداء الأمثل
* **حجم حمولة POST يبلغ 50 ميجابايت**
* **مهلة الإبقاء على الاتصال** يجب أن تكون أقل من مهلة الإبقاء على الاتصال في Server Pro

  يمكن تهيئة مهلة الإبقاء على الاتصال في Server Pro باستخدام متغير البيئة `NGINX_KEEPALIVE_TIMEOUT`. القيمة الافتراضية هي 65 ثانية.

  مع الإعداد الافتراضي، تعمل مهلة إبقاء الاتصال 60 ثانية في موازن التحميل.

  مع `NGINX_KEEPALIVE_TIMEOUT=120`، يمكن لموازن التحميل اختيار 115 ثانية.
* **عناوين IP للعملاء**

  اضبط ترويسة الطلب `X-Forwarded-For` إلى عنوان IP الخاص بالعميل.
* عندما **إنهاء SSL**

  يحتاج موازن التحميل إلى إضافة ترويسة الطلب `X-Forwarded-Proto: https`.

<details>

<summary>مثال على تهيئة HAProxy</summary>

```
global
  group haproxy
  user haproxy

  # تسجيل مفصل
  log stdout format raw local0 debug

defaults
  mode                    http
  option                  httpchk HEAD /status
  http-check              expect status 200
  default-server          check

  # تسجيل مفصل
  log                     global
  option                  httplog

  # أعد التوجيه إلى واجهة خلفية مختلفة إذا كانت الواجهة اللاصقة متوقفة
  option                  redispatch 1
  # هذه المحاولات المكررة مخصّصة لأخطاء اتصال TCP، وليس لاستجابات HTTP ذات الحالة 500
  retries                 3

  # جلسة لاصقة لمدة 24 ساعة من عدم النشاط -- يتم حذف مخرجات التجميع بعد 24 ساعة
  cookie                  server-pro-ha insert maxidle 24h

  # حاول الاتصال بأي واجهة خلفية لمدة دقيقة واحدة، ثم أعد 503
  timeout queue           1m
  # امنح مثيلات Server Pro 15 ثانية لبدء التشغيل
  timeout connect         15s

  # ألغِ الطلبات القادمة من عملاء بطيئين جدًا (اسمح بدقيقة واحدة من عدم النشاط عند قراءة طلب)
  timeout client          1m

  # اسمح بعمليات تجميع بطيئة -- الحد المبرمج في clsi هو 10 دقائق
  timeout server          10m

  # افصل المحرر بعد 23 ساعة -- ساعة واحدة بعد آخر استخدام لهم بالأمس
  timeout tunnel          23h

  # ملاحظة: يعمل سلوك keepalive في haproxy بشكل ممتاز مع إعداد keepalive الافتراضي في Server Pro.
  #       يقوم Haproxy بتنظيف الاتصالات في الخلفية وسيعيد توجيه الطلبات عند الحاجة.

listen server-pro-ha-http
  bind :80
  http-request redirect scheme https unless { ssl_fc }

listen server-pro-ha-https
  bind :443 ssl crt /etc/ssl/certs/ssl-key-and-certificate-bundle.pem

  # أخبر التطبيق أننا خلف https
  http-request set-header X-Forwarded-Proto https

  # أخبر التطبيق بعنوان IP الفعلي للعميل
  option forwardfor

  # راجع https://hstspreload.org/#deployment-recommendations
  http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload;"

  # وجّه حركة git إلى الحاوية الشقيقة لـ git-bridge
  use-server server-pro-ha-1 if { path_beg /git/ }

  # استكشاف الأخطاء
  http-response add-header X-Served-By %s
  stats enable
  stats uri /haproxy

  server server-pro-ha-1 198.18.1.1:80 cookie server-pro-ha-1
  server server-pro-ha-2 198.18.1.2:80 cookie server-pro-ha-2
  server server-pro-ha-3 198.18.1.3:80 cookie server-pro-ha-3
```

</details>

#### تهيئة Server Pro

**الأسرار**

يجب أن تتفق مثيلات Server Pro على أسرار مشتركة:

* `WEB_API_PASSWORD` (مصادقة واجهة برمجة تطبيقات الويب)
* `STAGING_PASSWORD` و `V1_HISTORY_PASSWORD` نفس القيمة (مصادقة السجل)
* `CRYPTO_RANDOM` (لملف تعريف ارتباط الجلسة)
* `OT_JWT_AUTH_KEY` (مصادقة السجل)

يجب تهيئة جميع هذه الأسرار بقيمة فريدة خاصة بها ومشاركتها بين المثيلات.

عند عدم تهيئتها وتوجيه طلبات المستخدم إلى مثيلات مختلفة من Server Pro، ستفشل طلباتهم في اجتياز فحوصات المصادقة، وسيتم إما إعادة توجيههم إلى صفحة تسجيل الدخول بشكل متكرر أو ستفشل إجراءاتهم في واجهة المستخدم بطرق غير متوقعة.

عند عدم تهيئتها، يستخدم Server Pro قيمة عشوائية جديدة لكل سر استنادًا إلى 32 بايتًا عشوائيًا من `/dev/urandom` (256 بت عشوائية).

{% code overflow="wrap" %}

```bash
# https://github.com/overleaf/overleaf/blob/45ca0f796c679103efd305ddbef28073c4a5de32/server-ce/init_scripts/00_regen_sharelatex_secrets.sh#L14
dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/'
```

{% endcode %}

**MongoDB**

أشر `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` للإصدارات `4.x` وما قبلها) إلى مثيل MongoDB المركزي.

**Redis**

أشر `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` للإصدارات `4.x` وما قبلها) و `REDIS_HOST` إلى مثيل Redis المركزي.

**تخزين متوافق مع S3 لملفات المشروع والسجل**

يرجى الاطلاع على الوثائق الخاصة بـ [تخزينًا متوافقًا مع S3](/on-premises/ar/althyeh/overleaf-toolkit/s3.md) للتفاصيل.

**الملفات المؤقتة**

سيكون الربط الافتراضي لقرص SSD محلي إلى `/var/lib/overleaf` (`/var/lib/sharelatex` للإصدارات `4.x` وما قبلها) كافيًا. وتأكد من الإشارة إلى `SANDBOXED_COMPILES_HOST_DIR` إلى نقطة التحميل على المضيف.

{% hint style="danger" %}
ننصح بشدة باستخدام قرص محلي. قد يؤدي استخدام أي نوع من الأقراص الشبكية (مثل NFS أو EBS) إلى أخطاء تجميع غير متوقعة ومشكلات أداء أخرى.
{% endhint %}

**تهيئة الوكيل**

* اضبط `OVERLEAF_BEHIND_PROXY=true` (`SHARELATEX_BEHIND_PROXY` للإصدارات `4.x` وما قبلها) للحصول على عناوين IP دقيقة للعملاء.
* اضبط `TRUSTED_PROXY_IPS` إلى عنوان IP الخاص بموازن التحميل (يمكن تحديد عدة CIDRs مفصولة بفاصلة).

**تكامل Git-bridge**

{% hint style="info" %}
أصبح Git-bridge متاحًا في Server Pro بدءًا من الإصدار 4.0.1.
{% endhint %}

تحتاج حاوية git-bridge إلى حاوية Server Pro شقيقة للتعامل مع طلبات git الواردة. يمكن لهذه الحاوية الشقيقة أن تخدم أيضًا حركة المستخدمين العادية. في التهيئة النموذجية، تعمل المثيل الأول كحاوية شقيقة لـ git-bridge، لكن يمكن لأي مثيل أن يؤدي هذا الدور فعليًا.

لماذا نحتاج إلى تعيين إحدى حاويات Server Pro كحاوية شقيقة لـ git-bridge؟ يقوم Server Pro بتسليم عناوين تنزيل لخدمة السجل إلى git-bridge. نحتاج إلى تهيئة عناوين السجل هذه بحيث تكون قابلة للوصول من حاوية git-bridge.

تهيئة حاوية Server Pro:

* اضبط `GIT_BRIDGE_ENABLED` إلى `'true'`
* اضبط `GIT_BRIDGE_HOST` إلى `<اسم حاوية git-bridge>` مثلًا `git-bridge`
* اضبط `GIT_BRIDGE_PORT` إلى `8000`
* اضبط `V1_HISTORY_URL` إلى `http://<اسم الحاوية الشقيقة لـ server-pro>:3100/api`.

  ملاحظة: هذا ضروري فقط على الحاوية الشقيقة لحاوية git-bridge. يمكن للمثيلات الأخرى استخدام عنوان URL لـ localhost، وهو الإعداد الافتراضي.

تهيئة حاوية git-bridge:

* اضبط `GIT_BRIDGE_API_BASE_URL` إلى `http://<اسم الحاوية الشقيقة لـ server-pro>/api/v0`، مثلًا `http://server-pro-ha-1/api/v0`
* اضبط `GIT_BRIDGE_OAUTH2_SERVER` إلى `http://<اسم الحاوية الشقيقة لـ server-pro>`، مثلًا `http://server-pro-ha-1`
* اضبط `GIT_BRIDGE_POSTBACK_BASE_URL` إلى `http://<اسم حاوية git-bridge>:8000`، مثلًا `http://git-bridge:8000`
* اضبط `GIT_BRIDGE_ROOT_DIR` إلى قرص بيانات git-bridge المثبت كربط، مثلًا `/data/git-bridge`

<details>

<summary>مثال على تهيئة docker-compose.yml</summary>

تُظهر التهيئة التالية إعدادًا مستقلًا بذاته. لكي تعمل النسخة التجريبية، تحتاج إلى توفير مفتاح/شهادة SSL صالحة وضبط `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` للإصدارات `4.x` وما قبلها). بالنسبة للإعداد الفعلي، يجب عليك استبدال الأسرار الوهمية بأسرار فعلية كما هو مذكور داخل السطر. بالنسبة للإعداد الفعلي، تحتاج إلى نقل الحاويات الفردية إلى عقد مخصصة وضبط عناوين IP لتناسب إعداد شبكتك المحلية.

```yaml
version: '2.2'

# إعداد التوسّع الأفقي الفعلي: اختر شبكتك الخاصة واستبدل عناوين IP في التهيئة.
networks:
    default:
        ipam:
            config:
                # هذا النطاق الفرعي جزء من نطاق فرعي محجوز يُستخدم للمعايرة
                # https://tools.ietf.org/html/rfc2544
                # النطاق الفرعي الكامل هو 198.18.0.0/15
                # استخدم 198.18.0.0/24 لموازن التحميل وقواعد البيانات
                # استخدم 198.18.1.0/24 لـ server-pro
                # استخدم 198.18.0.128/25 للحاوية المؤقتة
                - gateway: 198.18.0.1
                  ip_range: 198.18.0.128/25
                  subnet: 198.18.0.0/23

الخدمات:
    # إعداد التوسّع الأفقي الفعلي: شغّل haproxy خارج Docker على مضيف منفصل.
    lb:
        image: haproxy:2.6
        container_name: lb
        user: root
        logging:
            driver: local
            options:
                max-size: 10g
                max-file: '100'
        volumes:
            - ./haproxy.conf:/usr/local/etc/haproxy/haproxy.cfg
            # $ cat certificate.pem key.pem > ssl-key-and-certificate-bundle.pem
            - /path/to/ssl-key-and-certificate-bundle.pem:/etc/ssl/certs/ssl-key-and-certificate-bundle.pem
        # بديل عن "ports": استخدم شبكة المضيف لتجنّب عبء docker-proxy
        network_mode: host

        # بديل عن "network_mode: host": استخدم docker-proxy لعزل الشبكة
        # ports:
        #     - "80:80"
        #     - "443:443"
        # networks:
        #     default:
        #         ipv4_address: 198.18.0.2

        # إعداد التوسّع الأفقي الفعلي: أزل هذه لأنها تعمل على مضيفين آخرين.
        depends_on:
            server-pro-ha-1:
                condition: service_started
            server-pro-ha-2:
                condition: service_started
            server-pro-ha-3:
                condition: service_started

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية بجانب server-pro-ha-1.
    # بالنسبة إلى Server Pro 4.0 وما بعده.
    git-bridge:
        restart: always
        # يجب أن يتطابق الوسم مع وسم الحاوية `server-pro-ha-1`.
        image: quay.io/sharelatex/git-bridge:4.0.1
        volumes:
            # إعداد التوسّع الأفقي الفعلي: وجّه /data/git-bridge إلى قرص SSD محلي مخصّص.
            - ~/git_bridge_data:/data/git-bridge
        container_name: git-bridge
        environment:
            GIT_BRIDGE_API_BASE_URL: "http://server-pro-ha-1/api/v0"
            GIT_BRIDGE_OAUTH2_SERVER: "http://server-pro-ha-1"
            GIT_BRIDGE_POSTBACK_BASE_URL: "http://198.18.0.6:8000"
            GIT_BRIDGE_ROOT_DIR: "/data/git-bridge"
        user: root
        command: ["/server-pro-start.sh"]

        # إعداد التوسّع الأفقي الفعلي: شغّل على المضيف 198.18.0.6 وافتح المنفذ
        # ports:
        #     - "8000:8000"
        networks:
            default:
                ipv4_address: 198.18.0.6

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية على مضيف منفصل.
    server-pro-ha-1: &server-pro-ha-config
        restart: always
        image: quay.io/sharelatex/sharelatex-pro:4.0.1
        container_name: server-pro-ha-1
        hostname: server-pro-ha-1
        depends_on:
            # إعداد التوسّع الأفقي الفعلي: احتفظ بهذا الإدخال.
            git-bridge:
                condition: service_started

            # إعداد التوسّع الأفقي الفعلي: أزل الإدخالات أدناه لأنها تعمل على مضيفين آخرين.
            mongo:
                condition: service_healthy
            redis:
                condition: service_started
            minio:
                condition: service_started
            mongo_replica_set_setup:
                condition: service_completed_successfully
            minio_setup:
                condition: service_completed_successfully
        stop_grace_period: 60s
        volumes:
            - /tmp/scratch-disk1:/var/lib/sharelatex
            - /var/run/docker.sock:/var/run/docker.sock
        environment: &server-pro-ha-environment
            # إعداد التوسّع الأفقي الفعلي: وفّر نطاقك/اسم تطبيقك الخاص.
            OVERLEAF_SITE_URL: 'https://overleaf.example.com'
            OVERLEAF_APP_NAME: Server Pro Horizontal Scaling Demo

            OVERLEAF_MONGO_URL: mongodb://198.18.0.3/sharelatex
            OVERLEAF_REDIS_HOST: 198.18.0.4
            REDIS_HOST: 198.18.0.4

            ENABLED_LINKED_FILE_TYPES: 'project_file,project_output_file'
            EMAIL_CONFIRMATION_DISABLED: 'true'

            SANDBOXED_COMPILES: 'true'
            SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true'
            SANDBOXED_COMPILES_HOST_DIR: '/tmp/scratch-disk1/data/compiles'

            # S3
            # إعداد التوسّع الأفقي الفعلي: اختر بيانات اعتماد آمنة.
            OVERLEAF_FILESTORE_BACKEND: s3
            OVERLEAF_FILESTORE_USER_FILES_BUCKET_NAME: overleaf-user-files
            OVERLEAF_FILESTORE_TEMPLATE_FILES_BUCKET_NAME: overleaf-template-files
            OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID: OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID
            OVERLEAF_FILESTORE_S3_SECRET_ACCESS_KEY: OVERLEAF_FILESTORE_S3_SECRET_ACCESS_KEY
            OVERLEAF_FILESTORE_S3_ENDPOINT: http://198.18.0.5:9000
            OVERLEAF_FILESTORE_S3_PATH_STYLE: 'true'
            OVERLEAF_FILESTORE_S3_REGION: ''

            OVERLEAF_HISTORY_BACKEND: "s3"
            OVERLEAF_HISTORY_PROJECT_BLOBS_BUCKET: "overleaf-project-blobs"
            OVERLEAF_HISTORY_CHUNKS_BUCKET: "overleaf-chunks"
            OVERLEAF_HISTORY_S3_ACCESS_KEY_ID: "OVERLEAF_HISTORY_S3_ACCESS_KEY_ID"
            OVERLEAF_HISTORY_S3_SECRET_ACCESS_KEY: "OVERLEAF_HISTORY_S3_SECRET_ACCESS_KEY"
            OVERLEAF_HISTORY_S3_ENDPOINT: http://198.18.0.5:9000
            OVERLEAF_HISTORY_S3_PATH_STYLE: 'true'
            OVERLEAF_HISTORY_S3_REGION: ''
            # /S3

            # git-bridge
            GIT_BRIDGE_ENABLED: 'true'
            GIT_BRIDGE_HOST: 198.18.0.6
            GIT_BRIDGE_PORT: 8000
            # مطلوب فقط على النسخة الشقيقة من git-bridge
            V1_HISTORY_URL: "http://server-pro-ha-1:3100/api"
            # /git-bridge

            # التوسّع الأفقي
            # إعداد التوسّع الأفقي الفعلي: اختر بيانات اعتماد آمنة.
            WEB_API_PASSWORD: WEB_API_PASSWORD
            STAGING_PASSWORD: V1_HISTORY_PASSWORD
            V1_HISTORY_PASSWORD: V1_HISTORY_PASSWORD
            CRYPTO_RANDOM: CRYPTO_RANDOM
            OT_JWT_AUTH_KEY: OT_JWT_AUTH_KEY
            OVERLEAF_BEHIND_PROXY: 'true'
            # إعداد التوسّع الأفقي الفعلي: عناوين IP لموازنات التحميل
            TRUSTED_PROXY_IPS: 198.18.0.1,198.18.0.2
            # /التوسّع الأفقي

        # إعداد التوسّع الأفقي الفعلي: التشغيل على المضيف 198.18.1.1 وتوفير المنافذ
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.1

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية على مضيف منفصل.
    server-pro-ha-2:
        <<: *server-pro-ha-config
        hostname: server-pro-ha-2
        container_name: server-pro-ha-2
        volumes:
            - /tmp/scratch-disk2:/var/lib/sharelatex
            - /var/run/docker.sock:/var/run/docker.sock
        environment:
            <<: *server-pro-ha-environment
            SANDBOXED_COMPILES_HOST_DIR: '/tmp/scratch-disk2/data/compiles'
            V1_HISTORY_URL: "http://localhost:3100/api"

        # إعداد التوسّع الأفقي الفعلي: التشغيل على المضيف 198.18.1.2 وتوفير المنافذ
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.2

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية على مضيف منفصل.
    server-pro-ha-3:
        <<: *server-pro-ha-config
        hostname: server-pro-ha-3
        container_name: server-pro-ha-3
        volumes:
            - /tmp/scratch-disk3:/var/lib/sharelatex
            - /var/run/docker.sock:/var/run/docker.sock
        environment:
            <<: *server-pro-ha-environment
            SANDBOXED_COMPILES_HOST_DIR: '/tmp/scratch-disk3/data/compiles'
            V1_HISTORY_URL: "http://localhost:3100/api"

        # إعداد التوسّع الأفقي الفعلي: التشغيل على المضيف 198.18.1.3 وتوفير المنافذ
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.3

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية على مضيف منفصل.
    minio:
        image: minio/minio:RELEASE.2023-05-18T00-05-36Z
        container_name: minio
        command: server /data
        volumes:
            # إعداد التوسّع الأفقي الفعلي: شغّل minio مع عدة أقراص، راجع وثائق minio.
            - ~/minio_data:/data
        environment:
            # إعداد التوسّع الأفقي الفعلي: اختر بيانات اعتماد آمنة.
            MINIO_ROOT_USER: MINIO_ROOT_USER
            MINIO_ROOT_PASSWORD: MINIO_ROOT_PASSWORD

        # إعداد التوسّع الأفقي الفعلي: التشغيل على المضيف 198.18.0.5 وتوفير المنفذ
        # ports:
        #     - "9000:9000"
        networks:
            default:
                ipv4_address: 198.18.0.5

    # إعداد التوسّع الأفقي الفعلي: شغّل هذا الإعداد مرة واحدة على مضيف منفصل.
    minio_setup:
        depends_on:
            - minio
        image: minio/mc:RELEASE.2023-05-18T16-59-00Z
        entrypoint: sh
        الأمر:
            - '-c'
            # إعداد التوسّع الأفقي الفعلي: اختر بيانات اعتماد آمنة.
            - |
                mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD \
                || sleep 10 && \
                mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD \
                || sleep 10 && \
                mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD \
                || sleep 10 && \
                mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD

                mc mb --ignore-existing s3/overleaf-user-files
                mc mb --ignore-existing s3/overleaf-template-files
                mc admin user add s3 \
                  OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID \
                  OVERLEAF_FILESTORE_S3_SECRET_ACCESS_KEY

                mc mb --ignore-existing s3/overleaf-project-blobs
                mc mb --ignore-existing s3/overleaf-chunks
                mc admin user add s3 \
                  OVERLEAF_HISTORY_S3_ACCESS_KEY_ID \
                  OVERLEAF_HISTORY_S3_SECRET_ACCESS_KEY

                echo '
                  {
                    "Version": "2012-10-17",
                    "Statement": [
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:ListBucket"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-user-files"
                      },
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:PutObject",
                          "s3:GetObject",
                          "s3:DeleteObject"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-user-files/*"
                      },
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:ListBucket"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-template-files"
                      },
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:PutObject",
                          "s3:GetObject",
                          "s3:DeleteObject"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-template-files/*"
                      }
                    ]
                  }' > policy-filestore.json

                echo '
                  {
                    "Version": "2012-10-17",
                    "Statement": [
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:ListBucket"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-project-blobs"
                      },
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:PutObject",
                          "s3:GetObject",
                          "s3:DeleteObject"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-project-blobs/*"
                      },
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:ListBucket"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-chunks"
                      },
                      {
                        "Effect": "Allow",
                        "Action": [
                          "s3:PutObject",
                          "s3:GetObject",
                          "s3:DeleteObject"
                        ],
                        "Resource": "arn:aws:s3:::overleaf-chunks/*"
                      }
                    ]
                  }' > policy-history.json

                # ضع محتويات السياسة من القسم السابق في policy-filestore.json
                # تذكير: استبدل أسماء الحِزم وفقًا لذلك.
                mc admin policy create s3 overleaf-filestore policy-filestore.json
                mc admin policy attach s3 overleaf-filestore \
                  --user=OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID || true

                mc admin policy create s3 overleaf-history policy-history.json
                mc admin policy attach s3 overleaf-history \
                  --user=OVERLEAF_HISTORY_S3_ACCESS_KEY_ID || true

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية على مضيف منفصل.
    mongo:
        restart: always
        image: mongo:4.4
        container_name: mongo
        command: "--replSet overleaf"
        expose:
            - 27017
        volumes:
            - ~/mongo_data:/data/db
        healthcheck:
            test: echo 'db.stats().ok' | mongo localhost:27017/test --quiet
            interval: 10s
            timeout: 10s
            retries: 5

        # إعداد التوسّع الأفقي الفعلي: التشغيل على المضيف 198.18.0.3 وتوفير المنفذ
        # ports:
        #     - "27017:27017"
        networks:
            default:
                ipv4_address: 198.18.0.3

    mongo_replica_set_setup:
        image: mongo:4.4
        entrypoint: sh
        depends_on:
            mongo:
                condition: service_healthy
        الأمر:
            - '-c'
            - |
                mongo 198.18.0.3 --eval "rs.initiate({ _id: \"overleaf\", members: [ { _id: 0, host: \"198.18.0.3:27017\" } ] })"

    # إعداد التوسّع الأفقي الفعلي: شغّل هذه الحاوية على مضيف منفصل.
    redis:
        restart: always
        image: redis:6.2
        container_name: redis
        expose:
            - 6379
        volumes:
            - ~/redis_data:/data

        # إعداد التوسّع الأفقي الفعلي: التشغيل على المضيف 198.18.0.4 وتوفير المنفذ
        # ports:
        #     - "6379:6379"
        networks:
            default:
                ipv4_address: 198.18.0.4
```

</details>

#### الأجهزة

نوصي باستخدام مواصفات الأجهزة نفسها لجميع نسخ Server Pro المشاركة في التوسّع الأفقي.

تنطبق التوصيات العامة بشأن [مواصفات الأجهزة](/on-premises/ar/albda/requirements/hardware-requirements.md) على نسخ Server Pro.

#### ترقية Server Pro

كجزء من عملية الترقية، يقوم Server Pro تلقائيًا بتشغيل ترحيلات قاعدة البيانات. وهذه الترحيلات **لا** مُصممة لتُشغَّل من عدة نسخ بالتوازي.

يجب أن تنتهي الترحيلات قبل بدء تطبيق الويب الفعلي. يمكنك إما التحقق من السجلات بحثًا عن إدخال `اكتملت عمليات الترحيل` أو الانتظار حتى يقبل التطبيق حركة المرور.

تبدو عملية الترقية على النحو التالي:

1. جدولة نافذة صيانة
2. إيقاف جميع نسخ Server Pro
3. خذ نسخة احتياطية متسقة كما هو موضح في [الوثائق](/on-premises/ar/alsyanh/data-and-backups.md#performing-a-consistent-backup)
4. ابدأ نسخة واحدة من Server Pro بالإصدار الجديد
5. تحقق من أن النسخة الجديدة تعمل كما هو متوقع
6. شغّل النسخ الأخرى بالإصدار الجديد


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ayakaleaf-pro.ayaka.space/on-premises/ar/alsyanh/horizontal-scaling.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
