> ## 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.

# Escalado horizontal

<Check>
  Ayakaleaf Pro admite el escalado horizontal. Hemos probado y verificado que funciona correctamente con varias réplicas.
</Check>

Este documento enumera los requisitos técnicos y ofrece pautas para ejecutar Ayakaleaf Pro en más de un nodo.

<Danger>
  A partir de Server CE/Server Pro `5.0.3`, las variables de entorno se han renombrado de `SHARELATEX_*` a `OVERLEAF_*`.

  Si usas una versión `4.x` (o anterior), asegúrate de que las variables tengan el prefijo correspondiente (por ejemplo, `SHARELATEX_SITE_URL` en lugar de `OVERLEAF_SITE_URL`)
</Danger>

Configurar el escalado horizontal requiere un esfuerzo considerable. Te aconsejamos plantearte el escalado horizontal **solo** al alcanzar cierta escala. Por ejemplo, se ha configurado con éxito una instalación de Server Pro para 1.000 usuarios en total utilizando un único servidor con dos procesadores de 4 núcleos y 32 GB de memoria del sistema. Consulta la documentación de [requisitos de hardware](/es/on-premises/getting-started/requirements/hardware-requirements) para ver las recomendaciones.

Un despliegue de Server Pro con escalado horizontal implica un conjunto de componentes externos, como un balanceador de carga y un backend de almacenamiento compatible con S3.

Podemos ayudar a solucionar errores en los contenedores de Server Pro que puedan deberse a una configuración incorrecta y ofrecer consejos generales basados en este documento. Lamentablemente, no podemos ofrecer asistencia para configurar aplicaciones o sistemas de terceros.

La resolución de problemas técnicos específicos de tu hardware o software para proporcionar los componentes externos no está cubierta por nuestras condiciones de soporte.

### Requisitos

<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>

#### Almacenamiento de datos central y externo

El almacenamiento de datos en Server Pro puede dividirse en cuatro almacenes de datos:

* **MongoDB**

  * La mayoría de los datos se guardan en MongoDB.
  * Admitimos tanto una instancia local como una instancia externa, como [MongoDB](https://www.mongodb.com/atlas) Atlas (un servicio de MongoDB totalmente gestionado que se ejecuta sobre la infraestructura de AWS).<br />

  <strong>Nota:</strong> Lamentablemente, por el momento no hay soporte oficial para bases de datos compatibles con MongoDB como CosmoDB/DocumentDB, ya que no hemos probado Server Pro con ellas. Aunque **puede** ser posible desplegar Server Pro con bases de datos compatibles, solo admitimos oficialmente los despliegues que usan MongoDB.<br />
* **Redis**

  * Redis almacena datos temporales, como las actualizaciones pendientes de documentos antes de volcarlas en MongoDB.
  * Redis se usa para comunicar las actualizaciones de documentos entre los distintos servicios y para notificar al editor los cambios de estado de un proyecto determinado.
  * Redis se usa para almacenar las sesiones de usuario.
  * Admitimos tanto una instancia local como una instancia externa.<br />

  <strong>Nota:</strong> Lamentablemente, por el momento no hay soporte oficial para almacenes clave/valor compatibles con Redis como KeyDB/Valkey, ya que no hemos probado Server Pro con ellos. Aunque **puede** ser posible desplegar Server Pro con almacenes compatibles, solo admitimos oficialmente los despliegues que usan Redis.<br />
* **Archivos de proyecto y archivos de historial**

  * Los archivos de proyecto no editables se almacenan fuera de MongoDB.

    El nuevo sistema de historial de proyectos (a partir de Server Pro 3.5) también almacena el historial fuera de MongoDB.
  * Para instancias únicas pequeñas, admitimos tanto un sistema de archivos local (que puede estar respaldado por un SSD local, NFS o EBS) como un [sistema de almacenamiento de datos compatible con S3](/es/on-premises/configuration/overleaf-toolkit/s3).
  * Para el escalado horizontal, **solo** admitimos sistemas de almacenamiento de datos compatibles con S3.<br />

  <strong>Importante:</strong> NFS/Amazon EFS/Amazon EBS **no** son compatibles con el escalado horizontal. Consulta la sección de requisitos de [almacenamiento de hardware](/es/on-premises/getting-started/requirements/hardware-requirements#storage) sobre el escalado del almacenamiento en Server Pro para más detalles.
* **Archivos efímeros**
  * Las compilaciones de LaTeX deben ejecutarse en discos locales rápidos para un rendimiento óptimo. No es necesario conservar ni hacer copias de seguridad del resultado de la compilación.
  * El almacenamiento en búfer de las nuevas subidas de archivos y la creación de archivos zip de proyectos también se benefician del uso de un disco local.

<Danger>
  Recomendamos encarecidamente usar un disco local. Usar cualquier tipo de disco en red (como NFS o EBS) puede provocar errores de compilación inesperados y otros problemas de rendimiento.
</Danger>

#### **Git-bridge**

<Info>
  Git-bridge está disponible en Server Pro a partir de la versión 4.0.1.
</Info>

Los repositorios git se almacenan localmente en disco. No hay opciones de replicación disponibles. Git-bridge debe ejecutarse como **instancia única** (singleton). Para un rendimiento óptimo, recomendamos usar un disco local para los datos de git-bridge. Se deben hacer copias de seguridad periódicas del disco de datos de git-bridge.

Para el almacenamiento de datos con escalado horizontal, necesitas:

* una instancia central de MongoDB accesible desde todas las instancias de Server Pro
* una instancia central de Redis accesible desde todas las instancias de Server Pro
* un backend central de almacenamiento compatible con S3 para los archivos de proyecto y de historial
* un disco local en cada instancia para los archivos efímeros
* un disco local en la instancia que aloja el contenedor de git-bridge para los datos de git-bridge

#### Requisitos del balanceador de carga

* **Enrutamiento persistente**, por ejemplo mediante una cookie

  Este requisito se debe a los siguientes componentes:

  * La edición en tiempo real de Server Pro utiliza WebSockets, con XHR polling como alternativa. Cada sesión de edición tiene un estado local en el lado del servidor, y las solicitudes de una sesión de edición determinada siempre deben enrutarse a la misma instancia de Server Pro. La funcionalidad de colaboración utiliza [Pub/Sub](https://redis.io/docs/latest/develop/interact/pubsub/) de Redis para compartir actualizaciones entre varias instancias de Server Pro.
  * La compilación de LaTeX mantiene localmente la salida y la caché de compilación para un rendimiento óptimo. Tras enviar una solicitud de compilación a una instancia de Server Pro, las solicitudes posteriores de descarga del PDF o del log deben enrutarse a la misma instancia de Server Pro.
* **Tiempos de espera de solicitud largos** para permitir la compilación de documentos LaTeX grandes
* **Compatibilidad con WebSocket** para un rendimiento óptimo
* **Tamaño de carga útil POST de 50 MB**
* El **tiempo de espera keep-alive** debe ser inferior al tiempo de espera keep-alive de Server Pro

  El tiempo de espera keep-alive de Server Pro puede configurarse mediante la variable de entorno `NGINX_KEEPALIVE_TIMEOUT`. El valor predeterminado es 65 s.

  Con el valor predeterminado, funciona un tiempo de espera keep-alive de 60 s en el balanceador de carga.

  Con `NGINX_KEEPALIVE_TIMEOUT=120`, el balanceador de carga podría usar 115 s.
* **IP de los clientes**

  Establece la cabecera de solicitud `X-Forwarded-For` con la IP del cliente.
* Al **terminar SSL**

  El balanceador de carga debe añadir la cabecera de solicitud `X-Forwarded-Proto: https`.

<Accordion title="Ejemplo de configuración de 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>

#### Configuración de Server Pro

**Secretos**

Las instancias de Server Pro deben compartir los mismos secretos:

* `WEB_API_PASSWORD` (autenticación de la API web)
* `STAGING_PASSWORD` y `V1_HISTORY_PASSWORD` con el mismo valor (autenticación del historial)
* `CRYPTO_RANDOM` (para la cookie de sesión)
* `OT_JWT_AUTH_KEY` (autenticación del historial)

Cada uno de estos secretos debe configurarse con su propio valor único y compartirse entre las instancias.

Si no se configuran y las solicitudes de los usuarios se enrutan a distintas instancias de Server Pro, sus solicitudes no superarán las comprobaciones de autenticación y serán redirigidos con frecuencia a la página de inicio de sesión, o sus acciones en la interfaz fallarán de forma inesperada.

Si no se configuran, Server Pro utiliza un nuevo valor aleatorio para cada secreto, basado en 32 bytes aleatorios de `/dev/urandom` (256 bits aleatorios).

```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**

Haz que `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` en las versiones `4.x` y anteriores) apunte a la instancia central de MongoDB.

**Redis**

Haz que `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` en las versiones `4.x` y anteriores) y `REDIS_HOST` apunten a la instancia central de Redis.

**Almacenamiento compatible con S3 para archivos de proyecto y de historial**

Consulta la documentación sobre [almacenamiento compatible con S3](/es/on-premises/configuration/overleaf-toolkit/s3) para más detalles.

**Archivos efímeros**

El bind-mount predeterminado de un SSD local en `/var/lib/overleaf` (`/var/lib/sharelatex` en las versiones `4.x` y anteriores) será suficiente. Asegúrate de que `SANDBOXED_COMPILES_HOST_DIR` apunte al punto de montaje en la máquina anfitriona.

<Danger>
  Recomendamos encarecidamente usar un disco local. Usar cualquier tipo de disco en red (como NFS o EBS) puede provocar errores de compilación inesperados y otros problemas de rendimiento.
</Danger>

**Configuración del proxy**

* Establece `OVERLEAF_BEHIND_PROXY=true` (`SHARELATEX_BEHIND_PROXY` en las versiones `4.x` y anteriores) para obtener IP de cliente precisas.
* Establece `TRUSTED_PROXY_IPS` con la IP del balanceador de carga (se pueden especificar varios CIDR separados por comas).

**Integración con Git-bridge**

<Info>
  Git-bridge está disponible en Server Pro a partir de la versión 4.0.1.
</Info>

El contenedor de git-bridge necesita un contenedor de Server Pro asociado (sibling) para gestionar las solicitudes git entrantes. Este contenedor asociado también puede atender el tráfico normal de usuarios. En la configuración de ejemplo, la primera instancia actúa como contenedor asociado de git-bridge, aunque en realidad cualquier instancia podría cumplir esa función.

¿Por qué es necesario designar un contenedor de Server Pro como asociado de git-bridge? Server Pro entrega a git-bridge URL de descarga del servicio de historial. Necesitamos configurar estas URL de historial para que sean accesibles desde el contenedor de git-bridge.

Configuración del contenedor de Server Pro:

* Establece `GIT_BRIDGE_ENABLED` en `'true'`
* Establece `GIT_BRIDGE_HOST` en `<git-bridge container name>`, por ejemplo `git-bridge`
* Establece `GIT_BRIDGE_PORT` en `8000`
* Establece `V1_HISTORY_URL` en `http://<server-pro sibling container name>:3100/api`.

  Nota: esto solo es necesario en el contenedor asociado al contenedor de git-bridge. Las demás instancias pueden usar una URL de localhost, que es el valor predeterminado.

Configuración del contenedor de git-bridge:

* Establece `GIT_BRIDGE_API_BASE_URL` en `http://<server-pro sibling container name>/api/v0`, por ejemplo `http://server-pro-ha-1/api/v0`
* Establece `GIT_BRIDGE_OAUTH2_SERVER` en `http://<server-pro sibling container name>`, por ejemplo `http://server-pro-ha-1`
* Establece `GIT_BRIDGE_POSTBACK_BASE_URL` en `http://<git-bridge container name>:8000`, por ejemplo `http://git-bridge:8000`
* Establece `GIT_BRIDGE_ROOT_DIR` en el disco de datos de git-bridge montado mediante bind-mount, por ejemplo `/data/git-bridge`

<Accordion title="Ejemplo de configuración de docker-compose.yml">
  La siguiente configuración muestra una instalación autocontenida. Para que la demostración funcione, debes proporcionar una clave/certificado SSL válido y ajustar `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` en las versiones `4.x` y anteriores). En una instalación real, debes sustituir los secretos de prueba por secretos reales, como se indica en los comentarios. En una instalación real, debes trasladar cada contenedor a nodos dedicados y ajustar las direcciones IP a la configuración de tu red local.

  ```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>

#### Hardware

Recomendamos usar las mismas especificaciones de hardware para todas las instancias de Server Pro que participen en el escalado horizontal.

Se aplican las recomendaciones generales sobre [especificaciones de hardware](/es/on-premises/getting-started/requirements/hardware-requirements) para las instancias de Server Pro.

#### Actualizar Server Pro

Como parte del proceso de actualización, Server Pro ejecuta automáticamente migraciones de la base de datos. Estas migraciones **no** están diseñadas para ejecutarse desde varias instancias en paralelo.

Las migraciones deben finalizar antes de que se inicie la aplicación web propiamente dicha. Puedes buscar en los logs una entrada `Finished migrations` o esperar hasta que la aplicación acepte tráfico.

El procedimiento de actualización es el siguiente:

1. Programa una ventana de mantenimiento
2. Detén todas las instancias de Server Pro
3. Haz una copia de seguridad consistente como se describe en la [documentación](/es/on-premises/maintenance/data-and-backups#performing-a-consistent-backup)
4. Inicia una sola instancia de Server Pro con la nueva versión
5. Comprueba que la nueva instancia funciona como se espera
6. Levanta las demás instancias con la nueva versión


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