> 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/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 використовує WebSockets із резервним переходом на опитування 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

  # Перенаправити до іншого backend, якщо sticky-екземпляр недоступний
  option                  redispatch 1
  # Ці повторні спроби призначені для помилок TCP-з’єднання, а не для відповідей HTTP зі статусом 500
  retries                 3

  # Sticky-сеанс на 24 години бездіяльності — вихід компіляції видаляється через 24 години
  cookie                  server-pro-ha insert maxidle 24h

  # Спробувати підключитися до будь-якого backend протягом 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, змонтованого через bind, наприклад `/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 і dbs
                # Використайте 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: 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

            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/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://ayakaleaf-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.
