> For the complete documentation index, see [llms.txt](https://overleaf-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://overleaf-pro.ayaka.space/on-premises/uk/obslugovuvannya/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 користувачів загалом успішно налаштовано на одному сервері з двома 4-ядерними процесорами та 32 ГБ системної пам’яті. Див. [вимоги до обладнання](/on-premises/uk/pochatok-roboti/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/uk/konfiguraciya/overleaf-toolkit/s3.md).
  * Для горизонтального масштабування ми **лише** підтримуємо сумісні з S3 системи зберігання даних.<br>

  **Важливо:** NFS/Amazon EFS/Amazon EBS **не** підтримуються для горизонтального масштабування. Для деталей див. [апаратні вимоги до сховища](/on-premises/uk/pochatok-roboti/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

#### Вимоги до балансувальника навантаження

* **Постійне маршрутизування**, напр. з використанням cookie

  Ця вимога випливає з таких компонентів:

  * Можливість редагування в реальному часі в Server Pro використовує WebSocket із резервним переходом на опитування XHR. Кожна сесія редагування має локальний стан на сервері, і запити певної сесії редагування завжди потрібно маршрутизувати до того самого екземпляра Server Pro. Функція спільної роботи використовує Redis [Pub/Sub](https://redis.io/docs/latest/develop/interact/pubsub/) для обміну оновленнями між кількома екземплярами Server Pro.
  * Компіляція LaTeX зберігає вихідні дані та кеш компіляції локально для оптимальної продуктивності. Після надсилання запиту на компіляцію до одного екземпляра Server Pro наступні запити на завантаження PDF/журналу потрібно маршрутизувати до того самого екземпляра Server Pro.
* **Довгі тайм-аути запитів** для підтримки компіляції великих документів LaTeX
* **Підтримка WebSocket** для оптимальної продуктивності
* **Розмір POST-навантаження 50 МБ**
* **Тайм-аут keep-alive** має бути меншим за тайм-аут keep-alive Server Pro

  Тайм-аут keep-alive у Server Pro можна налаштувати за допомогою змінної середовища `NGINX_KEEPALIVE_TIMEOUT`. Значення за замовчуванням — 65 с.

  Із значенням за замовчуванням у балансувальнику навантаження працює тайм-аут keep-alive 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

  # Спробувати підключитися до будь-якого бекенда протягом 1 хв, потім повернути 503
  timeout queue           1m
  # Дати екземплярам Server Pro 15 с на запуск
  timeout connect         15s

  # Переривати запити від дуже повільних клієнтів (дозволяти 1 хв неактивності під час читання запиту)
  timeout client          1m

  # Дозволити повільні компіляції -- жорстко задане обмеження в clsi — 10 хв
  timeout server          10m

  # Від’єднати редактор через 23 год -- на 1 год попереду їхнього останнього використання вчора
  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` (автентифікація web api)
* `STAGING_PASSWORD` та `V1_HISTORY_PASSWORD` те саме значення (автентифікація історії)
* `CRYPTO_RANDOM` (для cookie сесії)
* `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/uk/konfiguraciya/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-адресу балансувальника навантаження (можна вказати кілька CIDR, розділених комою).

**Інтеграція 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 URL-адреси завантаження для служби історії. Нам потрібно налаштувати ці URL-адреси історії так, щоб вони були доступні з контейнера 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 для lb і db
                # Використовуйте 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

services:
    # Фактичне налаштування горизонтального масштабування: запускайте 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: завжди
        # Тег має відповідати тегу контейнера `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: завжди
        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

            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: завжди
        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: завжди
        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/uk/pochatok-roboti/requirements/hardware-requirements.md) для екземплярів Server Pro застосовуються.

#### Оновлення Server Pro

Під час процесу оновлення Server Pro автоматично запускає міграції бази даних. Ці міграції **не** призначені для запуску з кількох екземплярів паралельно.

Міграції мають завершитися до запуску власне вебзастосунку. Ви можете або перевірити журнали на наявність запису `Міграції завершено` або дочекатися, доки застосунок почне приймати трафік.

Процедура оновлення виглядає так:

1. Заплануйте вікно технічного обслуговування
2. Зупиніть усі екземпляри Server Pro
3. Створіть узгоджену резервну копію, як описано в [документацію](/on-premises/uk/obslugovuvannya/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://overleaf-pro.ayaka.space/on-premises/uk/obslugovuvannya/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.
