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

# Penskalaan horizontal

<Check>
  Ayakaleaf Pro mendukung penskalaan horizontal. Kami telah menguji dan memverifikasi bahwa Ayakaleaf Pro berjalan dengan benar dengan beberapa replika.
</Check>

Dokumen ini mencantumkan persyaratan teknis dan memberikan panduan untuk menjalankan Ayakaleaf Pro di lebih dari satu node.

<Danger>
  Mulai dari Server CE/Server Pro `5.0.3`, variabel lingkungan telah diganti namanya dari `SHARELATEX_*` menjadi `OVERLEAF_*`.

  Jika Anda menggunakan versi `4.x` (atau yang lebih lama), pastikan variabel diberi prefiks yang sesuai (misalnya `SHARELATEX_SITE_URL` alih-alih `OVERLEAF_SITE_URL`)
</Danger>

Menyiapkan penskalaan horizontal memerlukan upaya yang cukup besar. Kami menyarankan untuk mempertimbangkan penskalaan horizontal **hanya** ketika mencapai skala tertentu. Sebagai contoh, instalasi Server Pro untuk total 1.000 pengguna telah berhasil disiapkan menggunakan satu server dengan dua prosesor 4-core dan memori sistem 32GB. Lihat dokumentasi [persyaratan perangkat keras](/id/on-premises/getting-started/requirements/hardware-requirements) untuk rekomendasi.

Penerapan Server Pro dengan penskalaan horizontal melibatkan sejumlah komponen eksternal, seperti Load Balancer dan backend penyimpanan yang kompatibel dengan S3.

Kami dapat membantu memecahkan masalah error pada kontainer Server Pro yang mungkin disebabkan oleh kesalahan konfigurasi dan memberikan saran umum berdasarkan dokumen ini. Sayangnya, kami tidak dapat memberikan bantuan untuk mengonfigurasi aplikasi/sistem pihak ketiga.

Penyelesaian masalah teknis yang spesifik pada perangkat keras/perangkat lunak Anda untuk menyediakan komponen eksternal tidak tercakup dalam ketentuan dukungan kami.

### Persyaratan

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

#### Penyimpanan data eksternal terpusat

Penyimpanan data di Server Pro dapat dibagi menjadi empat penyimpanan data:

* **MongoDB**

  * Sebagian besar data disimpan secara persisten di MongoDB.
  * Kami mendukung instans lokal maupun instans eksternal, seperti [MongoDB](https://www.mongodb.com/atlas) Atlas (layanan MongoDB yang dikelola sepenuhnya dan berjalan di dalam infrastruktur AWS).<br />

  <strong>Catatan:</strong> Sayangnya, saat ini tidak ada dukungan resmi untuk database yang kompatibel dengan MongoDB seperti CosmoDB/DocumentDB, karena kami belum menguji Server Pro dengan database tersebut. Meskipun menerapkan Server Pro dengan database yang kompatibel **mungkin** dapat dilakukan, kami hanya secara resmi mendukung penerapan yang menggunakan MongoDB.<br />
* **Redis**

  * Redis menyimpan data sementara, seperti pembaruan dokumen yang tertunda sebelum di-flush ke MongoDB.
  * Redis digunakan untuk mengomunikasikan pembaruan dokumen antar layanan yang berbeda dan memberi tahu editor tentang perubahan status dalam suatu proyek.
  * Redis digunakan untuk menyimpan sesi pengguna.
  * Kami mendukung instans lokal maupun instans eksternal.<br />

  <strong>Catatan:</strong> Sayangnya, saat ini tidak ada dukungan resmi untuk penyimpanan key/value yang kompatibel dengan Redis seperti KeyDB/Valkey, karena kami belum menguji Server Pro dengan penyimpanan tersebut. Meskipun menerapkan Server Pro dengan penyimpanan yang kompatibel **mungkin** dapat dilakukan, kami hanya secara resmi mendukung penerapan yang menggunakan Redis.<br />
* **File proyek dan file History**

  * File proyek yang tidak dapat diedit disimpan di luar MongoDB.

    Sistem riwayat proyek yang baru (Server Pro 3.5 dan seterusnya) juga menyimpan riwayat di luar MongoDB.
  * Untuk instans tunggal yang kecil, kami mendukung sistem file lokal (yang dapat didukung oleh SSD lokal, NFS, atau EBS) maupun [sistem penyimpanan data yang kompatibel dengan S3](/id/on-premises/configuration/overleaf-toolkit/s3).
  * Untuk penskalaan horizontal, kami **hanya** mendukung sistem penyimpanan data yang kompatibel dengan S3.<br />

  <strong>Penting:</strong> NFS/Amazon EFS/Amazon EBS **tidak** didukung untuk penskalaan horizontal. Silakan lihat bagian persyaratan [penyimpanan perangkat keras](/id/on-premises/getting-started/requirements/hardware-requirements#storage) tentang penskalaan penyimpanan di Server Pro untuk detail lebih lanjut.
* **File sementara (ephemeral)**
  * Kompilasi LaTeX perlu berjalan pada disk lokal yang cepat untuk kinerja optimal. Output kompilasi tidak perlu disimpan secara persisten atau dicadangkan.
  * Buffering unggahan file baru dan pembuatan file zip proyek juga mendapat manfaat dari penggunaan disk lokal.

<Danger>
  Kami sangat menyarankan penggunaan disk lokal. Menggunakan jenis disk jaringan apa pun (seperti NFS atau EBS) dapat mengakibatkan error kompilasi yang tidak terduga dan masalah kinerja lainnya.
</Danger>

#### **Git-bridge**

<Info>
  Git-bridge tersedia di Server Pro mulai dari versi 4.0.1.
</Info>

Repositori git disimpan secara lokal di disk. Tidak ada opsi replikasi yang tersedia. Git-bridge harus dijalankan sebagai **singleton**. Untuk kinerja optimal, kami menyarankan penggunaan disk lokal untuk data git-bridge. Disk data git-bridge harus dicadangkan secara rutin.

Untuk penyimpanan data dengan penskalaan horizontal, Anda memerlukan:

* instans MongoDB terpusat yang dapat diakses dari semua instans Server Pro
* instans Redis terpusat yang dapat diakses dari semua instans Server Pro
* backend penyimpanan terpusat yang kompatibel dengan S3 untuk file proyek dan file riwayat
* disk lokal di setiap instans untuk file sementara
* disk lokal di instans yang meng-host kontainer git-bridge untuk data git-bridge

#### Persyaratan load balancer

* **Routing persisten**, misalnya menggunakan cookie

  Persyaratan ini berasal dari komponen-komponen berikut:

  * Kemampuan penyuntingan real-time di Server Pro menggunakan WebSockets dengan fallback ke XHR polling. Setiap sesi penyuntingan memiliki state lokal di sisi server dan permintaan dari suatu sesi penyuntingan harus selalu dirutekan ke instans Server Pro yang sama. Fitur kolaborasi menggunakan Redis [Pub/Sub](https://redis.io/docs/latest/develop/interact/pubsub/) untuk berbagi pembaruan antar beberapa instans Server Pro.
  * Kompilasi LaTeX menyimpan output dan cache kompilasi secara lokal untuk kinerja yang optimal. Setelah mengirim permintaan kompilasi ke satu instans Server Pro, permintaan unduhan PDF/log berikutnya harus dirutekan ke instans Server Pro yang sama.
* **Batas waktu permintaan yang panjang** untuk mendukung kompilasi dokumen LaTeX yang besar
* **Dukungan WebSocket** untuk kinerja optimal
* **Ukuran payload POST sebesar 50MB**
* **Batas waktu keep-alive** harus lebih rendah dari batas waktu keep-alive Server Pro

  Batas waktu keep-alive di Server Pro dapat dikonfigurasi menggunakan variabel lingkungan `NGINX_KEEPALIVE_TIMEOUT`. Nilai default-nya adalah 65 detik.

  Dengan nilai default, batas waktu keep-alive 60 detik pada load balancer akan berfungsi.

  Dengan `NGINX_KEEPALIVE_TIMEOUT=120`, load balancer dapat menggunakan 115 detik.
* **IP klien**

  Atur header permintaan `X-Forwarded-For` ke IP klien.
* Saat **mengakhiri SSL (SSL termination)**

  Load balancer perlu menambahkan header permintaan `X-Forwarded-Proto: https`.

<Accordion title="Contoh konfigurasi HAProxy">
  ```text theme={null}
  global
    group haproxy
    user haproxy

    # Verbose logging
    log stdout format raw local0 debug

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

    # Verbose logging
    log                     global
    option                  httplog

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

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

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

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

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

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

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

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

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

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

    # Tell the application the actual client ip
    option forwardfor

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

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

    # Debugging
    http-response add-header X-Served-By %s
    stats enable
    stats uri /haproxy

    server server-pro-ha-1 198.18.1.1:80 cookie server-pro-ha-1
    server server-pro-ha-2 198.18.1.2:80 cookie server-pro-ha-2
    server server-pro-ha-3 198.18.1.3:80 cookie server-pro-ha-3
  ```
</Accordion>

#### Konfigurasi Server Pro

**Secret**

Instans-instans Server Pro perlu menggunakan secret bersama yang sama:

* `WEB_API_PASSWORD` (autentikasi web api)
* `STAGING_PASSWORD` dan `V1_HISTORY_PASSWORD` dengan nilai yang sama (autentikasi history)
* `CRYPTO_RANDOM` (untuk cookie sesi)
* `OT_JWT_AUTH_KEY` (autentikasi history)

Semua secret ini perlu dikonfigurasi dengan nilai uniknya masing-masing dan dibagikan di antara instans-instans.

Jika tidak dikonfigurasi dan permintaan pengguna dirutekan ke instans Server Pro yang berbeda, permintaan mereka akan gagal dalam pemeriksaan autentikasi dan mereka akan sering diarahkan ke halaman login atau tindakan mereka di UI akan gagal dengan cara yang tidak terduga.

Jika tidak dikonfigurasi, Server Pro menggunakan nilai acak baru untuk setiap secret berdasarkan 32 byte acak dari `/dev/urandom` (256 bit acak).

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

**MongoDB**

Arahkan `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` untuk versi `4.x` dan yang lebih lama) ke instans MongoDB terpusat.

**Redis**

Arahkan `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` untuk versi `4.x` dan yang lebih lama) dan `REDIS_HOST` ke instans Redis terpusat.

**Penyimpanan yang kompatibel dengan S3 untuk file proyek dan file riwayat**

Silakan lihat dokumentasi tentang [penyimpanan yang kompatibel dengan S3](/id/on-premises/configuration/overleaf-toolkit/s3) untuk detailnya.

**File sementara (ephemeral)**

Bind-mount default dari SSD lokal ke `/var/lib/overleaf` (`/var/lib/sharelatex` untuk versi `4.x` dan yang lebih lama) sudah cukup. Pastikan untuk mengarahkan `SANDBOXED_COMPILES_HOST_DIR` ke titik mount di host.

<Danger>
  Kami sangat menyarankan penggunaan disk lokal. Menggunakan jenis disk jaringan apa pun (seperti NFS atau EBS) dapat mengakibatkan error kompilasi yang tidak terduga dan masalah kinerja lainnya.
</Danger>

**Konfigurasi proxy**

* Atur `OVERLEAF_BEHIND_PROXY=true` (`SHARELATEX_BEHIND_PROXY` untuk versi `4.x` dan yang lebih lama) untuk mendapatkan IP klien yang akurat.
* Atur `TRUSTED_PROXY_IPS` ke IP load balancer (beberapa CIDR dapat ditentukan, dipisahkan dengan koma).

**Integrasi Git-bridge**

<Info>
  Git-bridge tersedia di Server Pro mulai dari versi 4.0.1.
</Info>

Kontainer git-bridge memerlukan kontainer Server Pro pendamping (sibling) untuk menangani permintaan git yang masuk. Kontainer pendamping ini juga dapat melayani lalu lintas pengguna biasa. Dalam contoh konfigurasi, instans pertama berperan sebagai kontainer pendamping untuk git-bridge, tetapi sebenarnya instans mana pun dapat menjalankan fungsi tersebut.

Mengapa kita perlu menunjuk satu kontainer Server Pro sebagai pendamping untuk git-bridge? Server Pro memberikan URL unduhan untuk layanan history kepada git-bridge. Kita perlu mengonfigurasi URL history ini agar dapat diakses dari kontainer git-bridge.

Konfigurasi kontainer Server Pro:

* Atur `GIT_BRIDGE_ENABLED` ke `'true'`
* Atur `GIT_BRIDGE_HOST` ke `<git-bridge container name>`, misalnya `git-bridge`
* Atur `GIT_BRIDGE_PORT` ke `8000`
* Atur `V1_HISTORY_URL` ke `http://<server-pro sibling container name>:3100/api`.

  Catatan: Ini hanya diperlukan pada kontainer pendamping untuk kontainer git-bridge. Instans lainnya dapat menggunakan URL localhost, yang merupakan nilai default.

Konfigurasi kontainer git-bridge:

* Atur `GIT_BRIDGE_API_BASE_URL` ke `http://<server-pro sibling container name>/api/v0`, misalnya `http://server-pro-ha-1/api/v0`
* Atur `GIT_BRIDGE_OAUTH2_SERVER` ke `http://<server-pro sibling container name>`, misalnya `http://server-pro-ha-1`
* Atur `GIT_BRIDGE_POSTBACK_BASE_URL` ke `http://<git-bridge container name>:8000`, misalnya `http://git-bridge:8000`
* Atur `GIT_BRIDGE_ROOT_DIR` ke disk data git-bridge yang di-bind-mount, misalnya `/data/git-bridge`

<Accordion title="Contoh konfigurasi docker-compose.yml">
  Konfigurasi berikut menunjukkan penyiapan yang mandiri (self-contained). Agar demo berfungsi, Anda perlu menyediakan kunci/sertifikat SSL yang valid dan menyesuaikan `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` untuk versi `4.x` dan yang lebih lama). Untuk penyiapan sungguhan, Anda harus mengganti secret contoh dengan secret yang sebenarnya seperti yang dicatat di dalam konfigurasi. Untuk penyiapan sungguhan, Anda perlu memindahkan setiap kontainer ke node khusus dan menyesuaikan alamat IP dengan penyiapan jaringan lokal Anda.

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

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

  services:
      # Actual horizontal scaling setup: run haproxy outside docker on a separate host.
      lb:
          image: haproxy:2.6
          container_name: lb
          user: root
          logging:
              driver: local
              options:
                  max-size: 10g
                  max-file: '100'
          volumes:
              - ./haproxy.conf:/usr/local/etc/haproxy/haproxy.cfg
              # $ cat certificate.pem key.pem > ssl-key-and-certificate-bundle.pem
              - /path/to/ssl-key-and-certificate-bundle.pem:/etc/ssl/certs/ssl-key-and-certificate-bundle.pem
          # Alternative to "ports": use host network to avoid docker-proxy overhead
          network_mode: host

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

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

      # Actual horizontal scaling setup: run this container next to server-pro-ha-1.
      # For Server Pro 4.0 onwards.
      git-bridge:
          restart: always
          # The tag should match the `server-pro-ha-1` container tag.
          image: quay.io/sharelatex/git-bridge:4.0.1
          volumes:
              # Actual horizontal scaling setup: point /data/git-bridge at a dedicated local ssd.
              - ~/git_bridge_data:/data/git-bridge
          container_name: git-bridge
          environment:
              GIT_BRIDGE_API_BASE_URL: "http://server-pro-ha-1/api/v0"
              GIT_BRIDGE_OAUTH2_SERVER: "http://server-pro-ha-1"
              GIT_BRIDGE_POSTBACK_BASE_URL: "http://198.18.0.6:8000"
              GIT_BRIDGE_ROOT_DIR: "/data/git-bridge"
          user: root
          command: ["/server-pro-start.sh"]

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

      # Actual horizontal scaling setup: run this container on a separate host.
      server-pro-ha-1: &server-pro-ha-config
          restart: always
          image: quay.io/sharelatex/sharelatex-pro:4.0.1
          container_name: server-pro-ha-1
          hostname: server-pro-ha-1
          depends_on:
              # Actual horizontal scaling setup: keep this entry.
              git-bridge:
                  condition: service_started

              # Actual horizontal scaling setup: remove the ones below as they run on other hosts.
              mongo:
                  condition: service_healthy
              redis:
                  condition: service_started
              minio:
                  condition: service_started
              mongo_replica_set_setup:
                  condition: service_completed_successfully
              minio_setup:
                  condition: service_completed_successfully
          stop_grace_period: 60s
          volumes:
              - /tmp/scratch-disk1:/var/lib/sharelatex
              - /var/run/docker.sock:/var/run/docker.sock
          environment: &server-pro-ha-environment
              # Actual horizontal scaling setup: provide your own domain/app name.
              OVERLEAF_SITE_URL: 'https://overleaf.example.com'
              OVERLEAF_APP_NAME: Server Pro Horizontal Scaling Demo

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

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

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

              # S3
              # Actual horizontal scaling setup: pick secure credentials.
              OVERLEAF_FILESTORE_BACKEND: s3
              OVERLEAF_FILESTORE_USER_FILES_BUCKET_NAME: overleaf-user-files
              OVERLEAF_FILESTORE_TEMPLATE_FILES_BUCKET_NAME: overleaf-template-files
              OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID: OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID
              OVERLEAF_FILESTORE_S3_SECRET_ACCESS_KEY: OVERLEAF_FILESTORE_S3_SECRET_ACCESS_KEY
              OVERLEAF_FILESTORE_S3_ENDPOINT: http://198.18.0.5:9000
              OVERLEAF_FILESTORE_S3_PATH_STYLE: 'true'
              OVERLEAF_FILESTORE_S3_REGION: ''

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

              # git-bridge
              GIT_BRIDGE_ENABLED: 'true'
              GIT_BRIDGE_HOST: 198.18.0.6
              GIT_BRIDGE_PORT: 8000
              # Only needed on the sibling instance of git-bridge
              V1_HISTORY_URL: "http://server-pro-ha-1:3100/api"
              # /git-bridge

              # Horizontal scaling
              # Actual horizontal scaling setup: pick secure credentials.
              WEB_API_PASSWORD: WEB_API_PASSWORD
              STAGING_PASSWORD: V1_HISTORY_PASSWORD
              V1_HISTORY_PASSWORD: V1_HISTORY_PASSWORD
              CRYPTO_RANDOM: CRYPTO_RANDOM
              OT_JWT_AUTH_KEY: OT_JWT_AUTH_KEY
              OVERLEAF_BEHIND_PROXY: 'true'
              # Actual horizontal scaling setup: IPs of load balancers
              TRUSTED_PROXY_IPS: 198.18.0.1,198.18.0.2
              # /Horizontal scaling

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

      # Actual horizontal scaling setup: run this container on a separate host.
      server-pro-ha-2:
          <<: *server-pro-ha-config
          hostname: server-pro-ha-2
          container_name: server-pro-ha-2
          volumes:
              - /tmp/scratch-disk2:/var/lib/sharelatex
              - /var/run/docker.sock:/var/run/docker.sock
          environment:
              <<: *server-pro-ha-environment
              SANDBOXED_COMPILES_HOST_DIR: '/tmp/scratch-disk2/data/compiles'
              V1_HISTORY_URL: "http://localhost:3100/api"

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

      # Actual horizontal scaling setup: run this container on a separate host.
      server-pro-ha-3:
          <<: *server-pro-ha-config
          hostname: server-pro-ha-3
          container_name: server-pro-ha-3
          volumes:
              - /tmp/scratch-disk3:/var/lib/sharelatex
              - /var/run/docker.sock:/var/run/docker.sock
          environment:
              <<: *server-pro-ha-environment
              SANDBOXED_COMPILES_HOST_DIR: '/tmp/scratch-disk3/data/compiles'
              V1_HISTORY_URL: "http://localhost:3100/api"

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

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

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

      # Actual horizontal scaling setup: run this setup once on a separate host.
      minio_setup:
          depends_on:
              - minio
          image: minio/mc:RELEASE.2023-05-18T16-59-00Z
          entrypoint: sh
          command:
              - '-c'
              # Actual horizontal scaling setup: pick secure credentials.
              - |
                  mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD \
                  || sleep 10 && \
                  mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD \
                  || sleep 10 && \
                  mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD \
                  || sleep 10 && \
                  mc alias set s3 http://198.18.0.5:9000 MINIO_ROOT_USER MINIO_ROOT_PASSWORD

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

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

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

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

                  # Put the contents of the policy from the previous section in policy-filestore.json
                  # Reminder: Replace the bucket names accordingly.
                  mc admin policy create s3 overleaf-filestore policy-filestore.json
                  mc admin policy attach s3 overleaf-filestore \
                    --user=OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID || true

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

      # Actual horizontal scaling setup: run this container on a separate host.
      mongo:
          restart: always
          image: mongo:4.4
          container_name: mongo
          command: "--replSet overleaf"
          expose:
              - 27017
          volumes:
              - ~/mongo_data:/data/db
          healthcheck:
              test: echo 'db.stats().ok' | mongo localhost:27017/test --quiet
              interval: 10s
              timeout: 10s
              retries: 5

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

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

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

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

#### Perangkat keras

Kami menyarankan penggunaan spesifikasi perangkat keras yang sama untuk semua instans Server Pro yang terlibat dalam penskalaan horizontal.

Rekomendasi umum tentang [spesifikasi perangkat keras](/id/on-premises/getting-started/requirements/hardware-requirements) untuk instans Server Pro tetap berlaku.

#### Meningkatkan Server Pro

Sebagai bagian dari proses peningkatan, Server Pro secara otomatis menjalankan migrasi database. Migrasi ini **tidak** dirancang untuk dijalankan dari beberapa instans secara paralel.

Migrasi harus selesai sebelum aplikasi web yang sebenarnya dimulai. Anda dapat memeriksa log untuk entri `Finished migrations` atau menunggu hingga aplikasi menerima lalu lintas.

Prosedur peningkatan terlihat seperti ini:

1. Jadwalkan jendela pemeliharaan
2. Hentikan semua instans Server Pro
3. Buat cadangan yang konsisten seperti yang dijelaskan dalam [dokumentasi](/id/on-premises/maintenance/data-and-backups#performing-a-consistent-backup)
4. Jalankan satu instans Server Pro dengan versi baru
5. Validasi bahwa instans baru berfungsi seperti yang diharapkan
6. Jalankan instans-instans lainnya dengan versi baru


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