> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

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

<Check>
  يدعم Ayakaleaf Pro التوسّع الأفقي. لقد اختبرنا وتحققنا من أنه يعمل بشكل صحيح مع نسخ متماثلة متعددة.
</Check>

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

<Danger>
  بدءًا من Server CE/Server Pro `5.0.3`، أُعيدت تسمية متغيرات البيئة من `SHARELATEX_*` إلى `OVERLEAF_*`.

  إذا كنت تستخدم إصدارًا `4.x` (أو أقدم)، فيرجى التأكد من أن المتغيرات تحمل البادئة المناسبة (مثل `SHARELATEX_SITE_URL` بدلًا من `OVERLEAF_SITE_URL`)
</Danger>

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

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

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

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

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

<Frame>
  <img src="https://mintcdn.com/ayakaleaf-pro/GmaXa-Cu4QQRFT4C/images/on-premises/img-f045c922.jpg?fit=max&auto=format&n=GmaXa-Cu4QQRFT4C&q=85&s=fc2eadc84a202a5ad07dd34ca6f903d4" alt="" width="2617" height="2319" data-path="images/on-premises/img-f045c922.jpg" />
</Frame>

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

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

* **MongoDB**

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

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

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

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

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

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

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

<Danger>
  ننصح بشدة باستخدام قرص محلي. قد يؤدي استخدام أي نوع من الأقراص الشبكية (مثل NFS أو EBS) إلى أخطاء ترجمة غير متوقعة ومشكلات أداء أخرى.
</Danger>

#### **Git-bridge**

<Info>
  يتوفر Git-bridge في Server Pro بدءًا من الإصدار 4.0.1.
</Info>

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

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

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

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

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

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

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

  يمكن تهيئة مهلة keep-alive في Server Pro باستخدام متغير البيئة `NGINX_KEEPALIVE_TIMEOUT`. والقيمة الافتراضية هي 65s.

  مع القيمة الافتراضية، تعمل مهلة keep-alive بمقدار 60s في موازن الأحمال.

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

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

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

<Accordion title="نموذج لإعداد HAProxy">
  ```text theme={null}
  global
    group haproxy
    user haproxy

    # Verbose logging
    log stdout format raw local0 debug

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

    # Verbose logging
    log                     global
    option                  httplog

    # Reroute to a different backend if the sticky one is down
    option                  redispatch 1
    # These retries are for TCP connect errors, not on HTTP status 500 responses
    retries                 3

    # Sticky session for 24h of inactivity -- compile output is deleted after 24h
    cookie                  server-pro-ha insert maxidle 24h

    # Try to connect to any backend for 1min, then return 503
    timeout queue           1m
    # Give Server Pro instances 15s to startup
    timeout connect         15s

    # Abort requests from very slow clients (allow 1min of inactivity when reading a request)
    timeout client          1m

    # Allow slow compiles -- hard-coded limit in clsi is 10min
    timeout server          10m

    # Disconnect the editor after 23h -- 1h ahead of their last use yesterday
    timeout tunnel          23h

    # Note: The keepalive behavior in haproxy works great with the default keepalive setup in Server Pro.
    #       Haproxy is cleaning up connections in the background and it will redispatch requests when needed.

  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

    # Tell the application that we are behind https
    http-request set-header X-Forwarded-Proto https

    # Tell the application the actual client ip
    option forwardfor

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

    # Route git traffic to the sibling container of the git-bridge
    use-server server-pro-ha-1 if { path_beg /git/ }

    # Debugging
    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
  ```
</Accordion>

#### إعداد Server Pro

**الأسرار**

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

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

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

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

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

```bash wrap theme={null}
# 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+/'
```

**MongoDB**

وجّه `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` للإصدارات `4.x` وما قبلها) إلى نسخة MongoDB المركزية.

**Redis**

وجّه `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` للإصدارات `4.x` وما قبلها) و`REDIS_HOST` إلى نسخة Redis المركزية.

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

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

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

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

<Danger>
  ننصح بشدة باستخدام قرص محلي. قد يؤدي استخدام أي نوع من الأقراص الشبكية (مثل NFS أو EBS) إلى أخطاء ترجمة غير متوقعة ومشكلات أداء أخرى.
</Danger>

**إعداد الوكيل (Proxy)**

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

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

<Info>
  يتوفر Git-bridge في Server Pro بدءًا من الإصدار 4.0.1.
</Info>

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

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

إعداد حاوية Server Pro:

* عيّن `GIT_BRIDGE_ENABLED` إلى `'true'`
* عيّن `GIT_BRIDGE_HOST` إلى `<git-bridge container name>`، مثل `git-bridge`
* عيّن `GIT_BRIDGE_PORT` إلى `8000`
* عيّن `V1_HISTORY_URL` إلى `http://<server-pro sibling container name>:3100/api`.

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

إعداد حاوية git-bridge:

* عيّن `GIT_BRIDGE_API_BASE_URL` إلى `http://<server-pro sibling container name>/api/v0`، مثل `http://server-pro-ha-1/api/v0`
* عيّن `GIT_BRIDGE_OAUTH2_SERVER` إلى `http://<server-pro sibling container name>`، مثل `http://server-pro-ha-1`
* عيّن `GIT_BRIDGE_POSTBACK_BASE_URL` إلى `http://<git-bridge container name>:8000`، مثل `http://git-bridge:8000`
* عيّن `GIT_BRIDGE_ROOT_DIR` إلى قرص بيانات git-bridge المربوط (bind-mounted)، مثل `/data/git-bridge`

<Accordion title="نموذج لإعداد docker-compose.yml">
  يعرض الإعداد التالي بيئة قائمة بذاتها. لكي يعمل العرض التوضيحي، تحتاج إلى توفير مفتاح/شهادة SSL صالحة وتعديل `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` للإصدارات `4.x` وما قبلها). في الإعداد الفعلي، يجب استبدال الأسرار الوهمية بأسرار حقيقية كما هو موضح ضمن الشيفرة. وفي الإعداد الفعلي أيضًا، تحتاج إلى نقل الحاويات الفردية إلى عقد مخصصة وتعديل عناوين IP بما يتناسب مع إعداد شبكتك المحلية.

  ```yaml theme={null}
  version: '2.2'

  # Actual horizontal scaling setup: pick your own network and replace IPs in config.
  networks:
      default:
          ipam:
              config:
                  # This subnet is part of a reserved subnet used for benchmarking
                  # https://tools.ietf.org/html/rfc2544
                  # The full subnet is 198.18.0.0/15
                  # Use 198.18.0.0/24 for lb and dbs
                  # Use 198.18.1.0/24 for server-pro
                  # Use 198.18.0.128/25 for ephemeral container
                  - gateway: 198.18.0.1
                    ip_range: 198.18.0.128/25
                    subnet: 198.18.0.0/23

  services:
      # Actual horizontal scaling setup: run haproxy outside docker on a separate host.
      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
          # Alternative to "ports": use host network to avoid docker-proxy overhead
          network_mode: host

          # Alternative to "network_mode: host": use docker-proxy for network isolation
          # ports:
          #     - "80:80"
          #     - "443:443"
          # networks:
          #     default:
          #         ipv4_address: 198.18.0.2

          # Actual horizontal scaling setup: remove these as they run on other hosts.
          depends_on:
              server-pro-ha-1:
                  condition: service_started
              server-pro-ha-2:
                  condition: service_started
              server-pro-ha-3:
                  condition: service_started

      # Actual horizontal scaling setup: run this container next to server-pro-ha-1.
      # For Server Pro 4.0 onwards.
      git-bridge:
          restart: always
          # The tag should match the `server-pro-ha-1` container tag.
          image: quay.io/sharelatex/git-bridge:4.0.1
          volumes:
              # Actual horizontal scaling setup: point /data/git-bridge at a dedicated local 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"]

          # Actual horizontal scaling setup: run on host 198.18.0.6 and expose port
          # ports:
          #     - "8000:8000"
          networks:
              default:
                  ipv4_address: 198.18.0.6

      # Actual horizontal scaling setup: run this container on a separate host.
      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:
              # Actual horizontal scaling setup: keep this entry.
              git-bridge:
                  condition: service_started

              # Actual horizontal scaling setup: remove the ones below as they run on other hosts.
              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
              # Actual horizontal scaling setup: provide your own domain/app name.
              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
              # Actual horizontal scaling setup: pick secure credentials.
              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
              # Only needed on the sibling instance of git-bridge
              V1_HISTORY_URL: "http://server-pro-ha-1:3100/api"
              # /git-bridge

              # Horizontal scaling
              # Actual horizontal scaling setup: pick secure credentials.
              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'
              # Actual horizontal scaling setup: IPs of load balancers
              TRUSTED_PROXY_IPS: 198.18.0.1,198.18.0.2
              # /Horizontal scaling

          # Actual horizontal scaling setup: run on host 198.18.1.1 and expose ports
          # ports:
          #     - "80:80"
          networks:
              default:
                  ipv4_address: 198.18.1.1

      # Actual horizontal scaling setup: run this container on a separate host.
      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"

          # Actual horizontal scaling setup: run on host 198.18.1.2 and expose ports
          # ports:
          #     - "80:80"
          networks:
              default:
                  ipv4_address: 198.18.1.2

      # Actual horizontal scaling setup: run this container on a separate host.
      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"

          # Actual horizontal scaling setup: run on host 198.18.1.3 and expose ports
          # ports:
          #     - "80:80"
          networks:
              default:
                  ipv4_address: 198.18.1.3

      # Actual horizontal scaling setup: run this container on a separate host.
      minio:
          image: minio/minio:RELEASE.2023-05-18T00-05-36Z
          container_name: minio
          command: server /data
          volumes:
              # Actual horizontal scaling setup: run minio with multiple disks, see minio docs.
              - ~/minio_data:/data
          environment:
              # Actual horizontal scaling setup: pick secure credentials.
              MINIO_ROOT_USER: MINIO_ROOT_USER
              MINIO_ROOT_PASSWORD: MINIO_ROOT_PASSWORD

          # Actual horizontal scaling setup: run on host 198.18.0.5 and expose port
          # ports:
          #     - "9000:9000"
          networks:
              default:
                  ipv4_address: 198.18.0.5

      # Actual horizontal scaling setup: run this setup once on a separate host.
      minio_setup:
          depends_on:
              - minio
          image: minio/mc:RELEASE.2023-05-18T16-59-00Z
          entrypoint: sh
          command:
              - '-c'
              # Actual horizontal scaling setup: pick secure credentials.
              - |
                  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

                  # Put the contents of the policy from the previous section in policy-filestore.json
                  # Reminder: Replace the bucket names accordingly.
                  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

      # Actual horizontal scaling setup: run this container on a separate host.
      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

          # Actual horizontal scaling setup: run on host 198.18.0.3 and expose port
          # 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
          command:
              - '-c'
              - |
                  mongo 198.18.0.3 --eval "rs.initiate({ _id: \"overleaf\", members: [ { _id: 0, host: \"198.18.0.3:27017\" } ] })"

      # Actual horizontal scaling setup: run this container on a separate host.
      redis:
          restart: always
          image: redis:6.2
          container_name: redis
          expose:
              - 6379
          volumes:
              - ~/redis_data:/data

          # Actual horizontal scaling setup: run on host 198.18.0.4 and expose port
          # ports:
          #     - "6379:6379"
          networks:
              default:
                  ipv4_address: 198.18.0.4
  ```
</Accordion>

#### العتاد

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

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

#### ترقية Server Pro

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

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

تبدو إجراءات الترقية كما يلي:

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.