> 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/nl/onderhoud/horizontal-scaling.md).

# Horizontale schaalvergroting

Vanaf versie 3.5.6 ondersteunt Server Pro horizontale schaalvergroting.

Dit document bevat de technische vereisten en geeft richtlijnen voor het draaien van Server Pro op meer dan één node.

{% hint style="danger" %}
Vanaf Server CE/Server Pro `5.0.3` omgevingsvariabelen zijn omgedoopt van `SHARELATEX_*` naar `OVERLEAF_*`.

Als je een `4.x` versie (of eerder) gebruikt, zorg er dan voor dat de variabelen dienovereenkomstig met een voorvoegsel zijn voorzien (bijv. `SHARELATEX_SITE_URL` in plaats van `OVERLEAF_SITE_URL`)
{% endhint %}

Het opzetten van horizontale schaalvergroting vergt aanzienlijke inspanning. We adviseren om horizontale schaalvergroting te overwegen **alleen** wanneer een bepaalde schaal wordt bereikt. Als voorbeeld is een Server Pro-installatie voor in totaal 1.000 gebruikers succesvol opgezet met één server met twee 4-core processors en 32 GB systeemgeheugen. Zie de [hardwarevereisten](/on-premises/nl/aan-de-slag/requirements/hardware-requirements.md) documentatie voor aanbevelingen.

Een implementatie van Server Pro met horizontale schaalvergroting omvat een reeks externe componenten, zoals een load balancer en een S3-compatibele opslagbackend.

We kunnen helpen bij het oplossen van fouten in de Server Pro-containers die mogelijk het gevolg zijn van een verkeerde configuratie en algemeen advies geven op basis van dit document. Helaas kunnen we geen ondersteuning bieden bij het configureren van applicaties/systemen van derden.

Het oplossen van technische problemen die specifiek zijn voor uw hardware/software om de externe componenten te leveren, valt niet onder onze supportvoorwaarden.

### Vereisten

#### Externe, centrale gegevensopslag

De gegevensopslag in Server Pro kan worden opgesplitst in vier gegevensopslagplaatsen:

* **MongoDB**

  * Het grootste deel van de gegevens wordt in MongoDB opgeslagen.
  * We ondersteunen zowel een lokale instantie als een externe instantie, zoals [MongoDB](https://www.mongodb.com/atlas) Atlas (een volledig beheerde MongoDB-service die binnen de AWS-infrastructuur draait).<br>

  **Opmerking:** Helaas is er momenteel geen officiële ondersteuning voor MongoDB-compatibele databases zoals CosmoDB/DocumentDB, omdat we Server Pro ermee niet hebben getest. Hoewel het uitrollen van Server Pro met compatibele databases **mogelijk** is, ondersteunen we officieel alleen implementaties die MongoDB gebruiken.<br>
* **Redis**

  * Redis slaat tijdelijke gegevens op, zoals openstaande documentupdates voordat ze naar MongoDB worden weggeschreven.
  * Redis wordt gebruikt om documentupdates tussen verschillende services te communiceren en de editor te informeren over statuswijzigingen in een bepaald project.
  * Redis wordt gebruikt voor het opslaan van de gebruikerssessies.
  * We ondersteunen zowel een lokale instantie als een externe instantie.<br>

  **Opmerking:** Helaas is er momenteel geen officiële ondersteuning voor Redis-compatibele key/value-opslag zoals KeyDB/Valkey, omdat we Server Pro ermee niet hebben getest. Hoewel het uitrollen van Server Pro met compatibele opslag **mogelijk** mogelijk is, ondersteunen we officieel alleen implementaties die Redis gebruiken.<br>
* **Projectbestanden en geschiedenisbestanden**

  * Niet-bewerkbare projectbestanden worden buiten MongoDB opgeslagen.

    Het nieuwe systeem voor projectgeschiedenis (vanaf Server Pro 3.5) slaat de geschiedenis ook buiten MongoDB op.
  * Voor kleine single-instances ondersteunen we ofwel een lokaal bestandssysteem (dat kan worden ondersteund door een lokale SSD, NFS of EBS) of een [S3-compatibel gegevensopslagsysteem](/on-premises/nl/configuratie/overleaf-toolkit/s3.md).
  * Voor horizontale schaalvergroting **alleen** ondersteunen we S3-compatibele gegevensopslagsystemen.<br>

  **Belangrijk:** NFS/Amazon EFS/Amazon EBS zijn **niet** ondersteund voor horizontale schaalvergroting. Zie de [hardwareopslag](/on-premises/nl/aan-de-slag/requirements/hardware-requirements.md#storage) vereistensectie over het schalen van opslag in Server Pro voor meer details.
* **Tijdelijke bestanden**
  * LaTeX-compilaties moeten op snelle, lokale schijven draaien voor optimale prestaties. De uitvoer van de compilatie hoeft niet te worden bewaard of geback-upt.
  * Het bufferen van nieuwe bestandsuploads en het aanmaken van project-zipbestanden profiteert ook van het gebruik van een lokale schijf.

{% hint style="danger" %}
We adviseren sterk om een lokale schijf te gebruiken. Het gebruik van welke netwerk-schijf dan ook (zoals NFS of EBS) kan leiden tot onverwachte compileerfouten en andere prestatieproblemen.
{% endhint %}

#### **Git-bridge**

{% hint style="info" %}
Git-bridge is beschikbaar in Server Pro vanaf versie 4.0.1.
{% endhint %}

De git-repositories worden lokaal op schijf opgeslagen. Er zijn geen replicatieopties beschikbaar. Git-bridge moet worden uitgevoerd als een **singleton**. Voor optimale prestaties adviseren we om een lokale schijf te gebruiken voor git-bridge-gegevens. De gegevensschijf van git-bridge moet regelmatig worden geback-upt.

Voor gegevensopslag met horizontale schaalvergroting heb je nodig:

* een centrale MongoDB-instantie die toegankelijk is vanaf alle Server Pro-instanties
* een centrale Redis-instantie die toegankelijk is vanaf alle Server Pro-instanties
* een centrale S3-compatibele opslagbackend voor project- en geschiedenisbestanden
* een lokale schijf op elke instantie voor tijdelijke bestanden
* een lokale schijf op de instantie die de git-bridge-container host voor git-bridge-gegevens

#### Vereisten voor de load balancer

* **Persistente routering**, bijvoorbeeld met behulp van een cookie

  Deze vereiste vloeit voort uit deze componenten:

  * De realtime-bewerkingsfunctionaliteit in Server Pro gebruikt WebSockets met als terugvaloptie XHR-polling. Elke bewerksessie heeft lokale status aan de serverkant en de verzoeken van een bepaalde bewerksessie moeten altijd naar dezelfde Server Pro-instantie worden gerouteerd. De samenwerkingsfunctie gebruikt Redis [Pub/Sub](https://redis.io/docs/latest/develop/interact/pubsub/) voor het delen van updates tussen meerdere Server Pro-instanties.
  * De LaTeX-compilatie houdt de uitvoer en compile-cache lokaal voor optimale prestaties. Wanneer je een compileerverzoek naar één Server Pro-instantie verstuurt, moeten de volgende PDF-/logdownloadverzoeken naar dezelfde Server Pro-instantie worden gerouteerd.
* **Lange time-outs voor verzoeken** om de compilatie van grote LaTeX-documenten te ondersteunen
* **WebSocket-ondersteuning** voor optimale prestaties
* **POST-payloadgrootte van 50 MB**
* **Keep-alive-time-out** moet lager zijn dan de keep-alive-time-out van Server Pro

  De keep-alive-time-out in Server Pro kan worden geconfigureerd met behulp van de omgevingsvariabele `NGINX_KEEPALIVE_TIMEOUT`. De standaardwaarde is 65 s.

  Met de standaardinstelling werkt een keep-alive-time-out van 60 s in de load balancer.

  Met `NGINX_KEEPALIVE_TIMEOUT=120`, zou de load balancer 115 s kunnen kiezen.
* **Client-IP's**

  Stel de request-header `X-Forwarded-For` in op het client-IP.
* Wanneer **SSL beëindigen**

  De load balancer moet de request-header toevoegen `X-Forwarded-Proto: https`.

<details>

<summary>Voorbeeldconfiguratie van HAProxy</summary>

```
global
  group haproxy
  user haproxy

  # Uitgebreide logging
  log stdout format raw local0 debug

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

  # Uitgebreide logging
  log                     global
  option                  httplog

  # Routeren naar een andere backend als de sticky backend uitvalt
  option                  redispatch 1
  # Deze retries zijn voor TCP-verbindingsfouten, niet voor HTTP-status 500-antwoorden
  retries                 3

  # Sticky-sessie gedurende 24 uur inactiviteit -- compileeruitvoer wordt na 24 uur verwijderd
  cookie                  server-pro-ha insert maxidle 24h

  # Probeer 1 min met elke backend verbinding te maken en geef daarna 503 terug
  timeout queue           1m
  # Geef Server Pro-instanties 15 s om op te starten
  timeout connect         15s

  # Breek verzoeken van zeer trage clients af (sta 1 min inactiviteit toe bij het lezen van een verzoek)
  timeout client          1m

  # Sta trage compilaties toe -- de hardgecodeerde limiet in clsi is 10 min
  timeout server          10m

  # Verbreek de verbinding met de editor na 23 uur -- 1 uur na hun laatste gebruik gisteren
  timeout tunnel          23h

  # Opmerking: het keepalive-gedrag in haproxy werkt uitstekend met de standaard keepalive-instelling in Server Pro.
  #       Haproxy ruimt verbindingen op de achtergrond op en zal verzoeken opnieuw routeren wanneer nodig is.

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

  # Vertel de applicatie dat we achter https zitten
  http-request set-header X-Forwarded-Proto https

  # Vertel de applicatie het daadwerkelijke client-IP
  option forwardfor

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

  # Route gitverkeer naar de sibling-container van de 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
```

</details>

#### Server Pro-configuratie

**Geheimen**

De Server Pro-instanties moeten dezelfde gedeelde geheimen gebruiken:

* `WEB_API_PASSWORD` (auth voor web-API)
* `STAGING_PASSWORD` en `V1_HISTORY_PASSWORD` dezelfde waarde (auth voor geschiedenis)
* `CRYPTO_RANDOM` (voor sessiecookie)
* `OT_JWT_AUTH_KEY` (auth voor geschiedenis)

Al deze geheimen moeten worden geconfigureerd met hun eigen unieke waarde en gedeeld worden tussen de instanties.

Wanneer dit niet is geconfigureerd en gebruikersverzoeken naar verschillende Server Pro-instanties worden gerouteerd, zullen hun verzoeken de authenticatiecontroles niet doorstaan en worden ze ofwel vaak doorgestuurd naar de inlogpagina, of hun acties in de UI zullen op onverwachte manieren mislukken.

Wanneer dit niet is geconfigureerd, gebruikt Server Pro een nieuwe willekeurige waarde voor elk geheim op basis van 32 willekeurige bytes van `/dev/urandom` (256 willekeurige bits).

{% 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**

Verwijs `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` voor versies `4.x` en eerder) naar de centrale MongoDB-instantie.

**Redis**

Verwijs `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` voor versies `4.x` en eerder) en `REDIS_HOST` naar de centrale Redis-instantie.

**S3-compatibele opslag voor project- en geschiedenisbestanden**

Zie de documentatie over [S3-compatibele opslag](/on-premises/nl/configuratie/overleaf-toolkit/s3.md) voor details.

**Tijdelijke bestanden**

De standaard bind-mount van een lokale SSD naar `/var/lib/overleaf` (`/var/lib/sharelatex` voor versies `4.x` en eerder) is voldoende. Zorg ervoor dat je `SANDBOXED_COMPILES_HOST_DIR` naar het mountpunt op de host verwijst.

{% hint style="danger" %}
We adviseren sterk om een lokale schijf te gebruiken. Het gebruik van welke netwerk-schijf dan ook (zoals NFS of EBS) kan leiden tot onverwachte compileerfouten en andere prestatieproblemen.
{% endhint %}

**Proxyconfiguratie**

* Stel `OVERLEAF_BEHIND_PROXY=true` (`SHARELATEX_BEHIND_PROXY` voor versies `4.x` en eerder) voor accurate client-IP's.
* Stel `TRUSTED_PROXY_IPS` in op het IP-adres van de load balancer (meerdere CIDR's kunnen worden opgegeven, gescheiden door een komma).

**Integratie met Git-bridge**

{% hint style="info" %}
Git-bridge is beschikbaar in Server Pro vanaf versie 4.0.1.
{% endhint %}

De git-bridge-container heeft een sibling Server Pro-container nodig voor het afhandelen van binnenkomende git-verzoeken. Deze sibling-container kan ook regulier gebruikersverkeer afhandelen. In de voorbeeldconfiguratie fungeert de eerste instantie als sibling-container voor git-bridge, maar in feite kan elke instantie daarvoor dienen.

Waarom moeten we één Server Pro-container aanwijzen als sibling voor git-bridge? Server Pro geeft download-URL's voor de history-service door aan git-bridge. We moeten deze history-URL's zo configureren dat ze toegankelijk zijn vanuit de git-bridge-container.

Server Pro-containerconfiguratie:

* Stel `GIT_BRIDGE_ENABLED` naar `'true'`
* Stel `GIT_BRIDGE_HOST` naar `<git-bridge container name>` bijv. `git-bridge`
* Stel `GIT_BRIDGE_PORT` naar `8000`
* Stel `V1_HISTORY_URL` naar `http://<server-pro sibling container name>:3100/api`.

  Opmerking: dit is alleen nodig op de sibling-container voor de git-bridge-container. De andere instanties kunnen een localhost-URL gebruiken, wat de standaard is.

git-bridge-containerconfiguratie:

* Stel `GIT_BRIDGE_API_BASE_URL` naar `http://<server-pro sibling container name>/api/v0`, bijvoorbeeld `http://server-pro-ha-1/api/v0`
* Stel `GIT_BRIDGE_OAUTH2_SERVER` naar `http://<server-pro sibling container name>`, bijvoorbeeld `http://server-pro-ha-1`
* Stel `GIT_BRIDGE_POSTBACK_BASE_URL` naar `http://<git-bridge container name>:8000`, bijvoorbeeld `http://git-bridge:8000`
* Stel `GIT_BRIDGE_ROOT_DIR` naar de bind-gemounte git-bridge-gegevensschijf, bijvoorbeeld `/data/git-bridge`

<details>

<summary>Voorbeeldconfiguratie van docker-compose.yml</summary>

De volgende configuratie toont een op zichzelf staande opzet. Om de demo te laten werken, moet je een geldige SSL-sleutel/certificaat aanleveren en de `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` voor versies `4.x` en eerder). Voor een echte opzet moet je de dummy-geheimen vervangen door echte geheimen zoals inline vermeld. Voor een echte opzet moet je de afzonderlijke containers naar toegewijde nodes verplaatsen en de IP-adressen aanpassen aan je lokale netwerkopzet.

```yaml
version: '2.2'

# Echte opzet voor horizontale schaalvergroting: kies je eigen netwerk en vervang de IP's in de configuratie.
networks:
    default:
        ipam:
            config:
                # Dit subnet maakt deel uit van een gereserveerd subnet dat voor benchmarking wordt gebruikt
                # https://tools.ietf.org/html/rfc2544
                # Het volledige subnet is 198.18.0.0/15
                # Gebruik 198.18.0.0/24 voor lb en db's
                # Gebruik 198.18.1.0/24 voor server-pro
                # Gebruik 198.18.0.128/25 voor de tijdelijke container
                - gateway: 198.18.0.1
                  ip_range: 198.18.0.128/25
                  subnet: 198.18.0.0/23

services:
    # Echte opzet voor horizontale schaalvergroting: draai haproxy buiten docker op een aparte 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
        # Alternatief voor "ports": gebruik host-netwerk om docker-proxy-overhead te vermijden
        network_mode: host

        # Alternatief voor "network_mode: host": gebruik docker-proxy voor netwerkisolatie
        # ports:
        #     - "80:80"
        #     - "443:443"
        # networks:
        #     default:
        #         ipv4_address: 198.18.0.2

        # Echte opzet voor horizontale schaalvergroting: verwijder deze, omdat ze op andere hosts draaien.
        depends_on:
            server-pro-ha-1:
                condition: service_started
            server-pro-ha-2:
                condition: service_started
            server-pro-ha-3:
                condition: service_started

    # Echte opzet voor horizontale schaalvergroting: draai deze container naast server-pro-ha-1.
    # Voor Server Pro 4.0 en hoger.
    git-bridge:
        restart: always
        # De tag moet overeenkomen met de container-tag van `server-pro-ha-1`.
        image: quay.io/sharelatex/git-bridge:4.0.1
        volumes:
            # Echte opzet voor horizontale schaalvergroting: wijs /data/git-bridge aan een toegewijde lokale ssd toe.
            - ~/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"]

        # Echte opzet voor horizontale schaalvergroting: draai op host 198.18.0.6 en exposeer poort
        # ports:
        #     - "8000:8000"
        networks:
            default:
                ipv4_address: 198.18.0.6

    # Echte opzet voor horizontale schaalvergroting: draai deze container op een aparte 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:
            # Echte opzet voor horizontale schaalvergroting: behoud deze entry.
            git-bridge:
                condition: service_started

            # Echte opzet voor horizontale schaalvergroting: verwijder de onderstaande, omdat ze op andere hosts draaien.
            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
            # Echte opzet voor horizontale schaalvergroting: lever je eigen domein/app-naam aan.
            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
            # Echte opzet voor horizontale schaalvergroting: kies veilige inloggegevens.
            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
            # Alleen nodig op de zusterinstantie van git-bridge
            V1_HISTORY_URL: "http://server-pro-ha-1:3100/api"
            # /git-bridge

            # Horizontale schaling
            # Echte opzet voor horizontale schaalvergroting: kies veilige inloggegevens.
            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'
            # Werkelijke horizontale schaalconfiguratie: IP's van loadbalancers
            TRUSTED_PROXY_IPS: 198.18.0.1,198.18.0.2
            # /Horizontale schaling

        # Werkelijke horizontale schaalconfiguratie: uitvoeren op host 198.18.1.1 en poorten blootstellen
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.1

    # Echte opzet voor horizontale schaalvergroting: draai deze container op een aparte 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"

        # Werkelijke horizontale schaalconfiguratie: uitvoeren op host 198.18.1.2 en poorten blootstellen
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.2

    # Echte opzet voor horizontale schaalvergroting: draai deze container op een aparte 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"

        # Werkelijke horizontale schaalconfiguratie: uitvoeren op host 198.18.1.3 en poorten blootstellen
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.3

    # Echte opzet voor horizontale schaalvergroting: draai deze container op een aparte host.
    minio:
        image: minio/minio:RELEASE.2023-05-18T00-05-36Z
        container_name: minio
        command: server /data
        volumes:
            # Werkelijke horizontale schaalconfiguratie: voer minio uit met meerdere schijven, zie de minio-documentatie.
            - ~/minio_data:/data
        environment:
            # Echte opzet voor horizontale schaalvergroting: kies veilige inloggegevens.
            MINIO_ROOT_USER: MINIO_ROOT_USER
            MINIO_ROOT_PASSWORD: MINIO_ROOT_PASSWORD

        # Werkelijke horizontale schaalconfiguratie: uitvoeren op host 198.18.0.5 en poort blootstellen
        # ports:
        #     - "9000:9000"
        networks:
            default:
                ipv4_address: 198.18.0.5

    # Werkelijke horizontale schaalconfiguratie: voer deze configuratie eenmaal uit op een aparte host.
    minio_setup:
        depends_on:
            - minio
        image: minio/mc:RELEASE.2023-05-18T16-59-00Z
        entrypoint: sh
        opdracht:
            - '-c'
            # Echte opzet voor horizontale schaalvergroting: kies veilige inloggegevens.
            - |
                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

                # Plaats de inhoud van het beleid uit de vorige sectie in policy-filestore.json
                # Herinnering: vervang de bucketnamen dienovereenkomstig.
                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

    # Echte opzet voor horizontale schaalvergroting: draai deze container op een aparte 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

        # Werkelijke horizontale schaalconfiguratie: uitvoeren op host 198.18.0.3 en poort blootstellen
        # 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
        opdracht:
            - '-c'
            - |
                mongo 198.18.0.3 --eval "rs.initiate({ _id: \"overleaf\", members: [ { _id: 0, host: \"198.18.0.3:27017\" } ] })"

    # Echte opzet voor horizontale schaalvergroting: draai deze container op een aparte host.
    redis:
        restart: always
        image: redis:6.2
        container_name: redis
        expose:
            - 6379
        volumes:
            - ~/redis_data:/data

        # Werkelijke horizontale schaalconfiguratie: uitvoeren op host 198.18.0.4 en poort blootstellen
        # ports:
        #     - "6379:6379"
        networks:
            default:
                ipv4_address: 198.18.0.4
```

</details>

#### Hardware

We raden aan om voor alle Server Pro-instanties die deelnemen aan horizontale schaling dezelfde hardwarespecificaties te gebruiken.

De algemene aanbevelingen voor [hardwarespecificaties](/on-premises/nl/aan-de-slag/requirements/hardware-requirements.md) voor Server Pro-instanties zijn van toepassing.

#### Server Pro upgraden

Als onderdeel van het upgradeproces voert Server Pro automatisch databasemigraties uit. Deze migraties zijn **niet** ontworpen om parallel vanaf meerdere instanties te worden uitgevoerd.

De migraties moeten zijn voltooid voordat de daadwerkelijke webapplicatie wordt gestart. Je kunt de logs controleren op een vermelding van `Migraties voltooid` of wachten tot de applicatie verkeer accepteert.

De upgradeprocedure ziet er als volgt uit:

1. Plan een onderhoudsvenster
2. Stop alle instanties van Server Pro
3. Maak een consistente back-up zoals beschreven in de [documentatie](/on-premises/nl/onderhoud/data-and-backups.md#performing-a-consistent-backup)
4. Start één instantie van Server Pro met de nieuwe versie
5. Controleer of de nieuwe instantie werkt zoals verwacht
6. Breng de andere instanties met de nieuwe versie online


---

# 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/nl/onderhoud/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.
