> For the complete documentation index, see [llms.txt](https://ayakaleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayakaleaf-pro.ayaka.space/on-premises/es/mantenimiento/horizontal-scaling.md).

# Escalado horizontal

A partir de la versión 3.5.6, Server Pro admite el escalado horizontal.

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

{% hint style="danger" %}
A partir de Server CE/Server Pro `5.0.3` las variables de entorno se han rebautizado de `SHARELATEX_*` a `OVERLEAF_*`.

Si estás usando una `4.x` versión (o anterior), asegúrate de que las variables tengan el prefijo correspondiente (p. ej. `SHARELATEX_SITE_URL` en lugar de `OVERLEAF_SITE_URL`)
{% endhint %}

Configurar el escalado horizontal requiere una cantidad significativa de esfuerzo. Aconsejamos considerar el escalado horizontal **solo** al alcanzar cierta escala. Como ejemplo, una instalación de Server Pro para 1.000 usuarios totales se ha configurado con éxito usando un único servidor con dos procesadores de 4 núcleos y 32 GB de memoria del sistema. Consulta la [requisitos de hardware](/on-premises/es/primeros-pasos/requirements/hardware-requirements.md) documentación para obtener recomendaciones.

Una implementación 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 diagnosticar errores en los contenedores de Server Pro que puedan ser el resultado de una configuración incorrecta y ofrecer consejos generales basados en este documento. Lamentablemente, no podemos ayudar a configurar aplicaciones/sistemas de terceros.

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

### Requisitos

#### Almacenamiento de datos externo y centralizado

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

* **MongoDB**

  * La mayor parte de los datos se persiste en MongoDB.
  * Admitimos una instancia local o una instancia externa, como [MongoDB](https://www.mongodb.com/atlas) Atlas (un servicio de MongoDB totalmente administrado que se ejecuta dentro de la infraestructura de AWS).<br>

  **Nota:** 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 implementar Server Pro con bases de datos compatibles **podría** ser posible, solo admitimos oficialmente implementaciones que usen MongoDB.<br>
* **Redis**

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

  **Nota:** Lamentablemente, por el momento no hay soporte oficial para almacenes de claves/valores compatibles con Redis como KeyDB/Valkey, ya que no hemos probado Server Pro con ellos. Aunque implementar Server Pro con almacenes compatibles **podría** podría ser posible, solo admitimos oficialmente implementaciones que usen Redis.<br>
* **Archivos del proyecto y archivos de historial**

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

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

  **Importante:** NFS/Amazon EFS/Amazon EBS son **no** admitidos para el escalado horizontal. Consulta la sección [de almacenamiento de hardware](/on-premises/es/primeros-pasos/requirements/hardware-requirements.md#storage) sobre requisitos para escalar el 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. El resultado de la compilación no necesita persistirse ni respaldarse.
  * El almacenamiento en búfer de nuevas cargas de archivos y la creación de archivos zip de proyectos también se benefician del uso de un disco local.

{% hint style="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.
{% endhint %}

#### **Git-bridge**

{% hint style="info" %}
Git-bridge está disponible en Server Pro a partir de la versión 4.0.1.
{% endhint %}

Los repositorios git se almacenan localmente en disco. No hay opciones de replicación disponibles. Git-bridge debe ejecutarse como un **singleton**. Para un rendimiento óptimo, recomendamos usar un disco local para los datos de git-bridge. El disco de datos de git-bridge debe respaldarse regularmente.

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 de almacenamiento central compatible con S3 para los archivos del proyecto y del historial
* un disco local en cada instancia para los archivos efímeros
* un disco local en la instancia que aloja el contenedor git-bridge para los datos de git-bridge

#### Requisitos del balanceador de carga

* **Enrutamiento persistente**, p. ej., usando una cookie

  Este requisito surge de estos componentes:

  * La capacidad de edición en tiempo real en Server Pro usa WebSockets con una alternativa de sondeo XHR. Cada sesión de edición tiene 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 función de colaboración usa Redis [Pub/Sub](https://redis.io/docs/latest/develop/interact/pubsub/) para compartir actualizaciones entre varias instancias de Server Pro.
  * La compilación de LaTeX mantiene la salida y la caché de compilación localmente para un rendimiento óptimo. Al enviar una solicitud de compilación a una instancia de Server Pro, las siguientes solicitudes de descarga de PDF/log deben enrutarse a la misma instancia de Server Pro.
* **Tiempo de espera de solicitud largo** para admitir la compilación de documentos LaTeX grandes
* **Compatibilidad con WebSocket** para un rendimiento óptimo
* **carga útil POST de 50 MB**
* **Tiempo de espera keep-alive** debe ser inferior al tiempo de espera keep-alive de Server Pro

  El tiempo de espera keep-alive en 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 elegir 115 s.
* **IPs de cliente**

  Establece el encabezado de la solicitud `X-Forwarded-For` en la IP del cliente.
* Cuando **terminación SSL**

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

<details>

<summary>Ejemplo de configuración de HAProxy</summary>

```
global
  group haproxy
  user haproxy

  # Registro detallado
  log stdout format raw local0 debug

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

  # Registro detallado
  log                     global
  option                  httplog

  # Reenviar a un backend diferente si el persistente está caído
  option                  redispatch 1
  # Estos reintentos son para errores de conexión TCP, no para respuestas HTTP con estado 500
  retries                 3

  # Sesión persistente durante 24 h de inactividad: la salida de compilación se elimina después de 24 h
  cookie                  server-pro-ha insert maxidle 24h

  # Intenta conectarte a cualquier backend durante 1 min, luego devuelve 503
  timeout queue           1m
  # Dale a las instancias de Server Pro 15 s para iniciarse
  timeout connect         15s

  # Abortar solicitudes de clientes muy lentos (permitir 1 min de inactividad al leer una solicitud)
  timeout client          1m

  # Permitir compilaciones lentas: el límite codificado en clsi es de 10 min
  timeout server          10m

  # Desconectar el editor después de 23 h: 1 h antes de su último uso ayer
  timeout tunnel          23h

  # Nota: El comportamiento keepalive en haproxy funciona muy bien con la configuración keepalive predeterminada en Server Pro.
  #       Haproxy limpia las conexiones en segundo plano y reenviará las solicitudes cuando sea necesario.

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

  # Indicar a la aplicación que estamos detrás de https
  http-request set-header X-Forwarded-Proto https

  # Indicar a la aplicación la IP real del cliente
  option forwardfor

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

  # Enrutar el tráfico git al contenedor hermano de git-bridge
  use-server server-pro-ha-1 if { path_beg /git/ }

  # Depuración
  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>

#### Configuración de Server Pro

**Secretos**

Las instancias de Server Pro deben coincidir en los secretos compartidos:

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

Todos estos secretos deben configurarse con su propio valor único y compartirse entre las instancias.

Si no se configuran y las solicitudes de los usuarios se enrutan a diferentes instancias de Server Pro, su solicitud fallará en las comprobaciones de autenticación y se les redirigirá con frecuencia a la página de inicio de sesión o sus acciones en la interfaz fallarán de formas inesperadas.

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

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

Apunte `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` para las versiones `4.x` y anteriores) en la instancia central de MongoDB.

**Redis**

Apunte `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` para las versiones `4.x` y anteriores) y `REDIS_HOST` en la instancia central de Redis.

**Almacenamiento compatible con S3 para los archivos del proyecto y del historial**

Consulta la documentación sobre [almacenamiento compatible con S3](/on-premises/es/configuracion/overleaf-toolkit/s3.md) para obtener detalles.

**Archivos efímeros**

El montaje vinculado predeterminado de un SSD local a `/var/lib/overleaf` (`/var/lib/sharelatex` para las versiones `4.x` y anteriores) será suficiente. Asegúrate de apuntar `SANDBOXED_COMPILES_HOST_DIR` al punto de montaje en el host.

{% hint style="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.
{% endhint %}

**Configuración del proxy**

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

**Integración de git-bridge**

{% hint style="info" %}
Git-bridge está disponible en Server Pro a partir de la versión 4.0.1.
{% endhint %}

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

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

Configuración del contenedor Server Pro:

* Establece `GIT_BRIDGE_ENABLED` a `'true'`
* Establece `GIT_BRIDGE_HOST` a `<nombre del contenedor git-bridge>` p. ej., `git-bridge`
* Establece `GIT_BRIDGE_PORT` a `8000`
* Establece `V1_HISTORY_URL` a `http://<nombre del contenedor hermano de server-pro>:3100/api`.

  Nota: Esto solo es necesario en el contenedor hermano para el contenedor git-bridge. Las otras instancias pueden usar una URL localhost, que es la predeterminada.

Configuración del contenedor git-bridge:

* Establece `GIT_BRIDGE_API_BASE_URL` a `http://<nombre del contenedor hermano de server-pro>/api/v0`, por ejemplo, `http://server-pro-ha-1/api/v0`
* Establece `GIT_BRIDGE_OAUTH2_SERVER` a `http://<nombre del contenedor hermano de server-pro>`, por ejemplo, `http://server-pro-ha-1`
* Establece `GIT_BRIDGE_POSTBACK_BASE_URL` a `http://<nombre del contenedor git-bridge>:8000`, por ejemplo, `http://git-bridge:8000`
* Establece `GIT_BRIDGE_ROOT_DIR` al disco de datos de git-bridge montado con bind, p. ej., `/data/git-bridge`

<details>

<summary>Ejemplo de configuración de docker-compose.yml</summary>

La siguiente configuración muestra una configuración autónoma. Para que la demo funcione, debes proporcionar una clave/certificado SSL válido y ajustar la `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` para las versiones `4.x` y anteriores). Para una configuración real, debes reemplazar los secretos ficticios por secretos reales, como se indica en línea. Para una configuración real, debes mover los contenedores individuales a nodos dedicados y ajustar las direcciones IP a tu configuración de red local.

```yaml
version: '2.2'

# Configuración real de escalado horizontal: elige tu propia red y reemplaza las IP en la configuración.
networks:
    default:
        ipam:
            config:
                # Esta subred forma parte de una subred reservada usada para benchmarking
                # https://tools.ietf.org/html/rfc2544
                # La subred completa es 198.18.0.0/15
                # Usa 198.18.0.0/24 para lb y dbs
                # Usa 198.18.1.0/24 para server-pro
                # Usa 198.18.0.128/25 para contenedor efímero
                - gateway: 198.18.0.1
                  ip_range: 198.18.0.128/25
                  subnet: 198.18.0.0/23

services:
    # Configuración real de escalado horizontal: ejecuta haproxy fuera de docker en un host separado.
    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
        # Alternativa a "ports": usa la red del host para evitar la sobrecarga de docker-proxy
        network_mode: host

        # Alternativa a "network_mode: host": usa docker-proxy para el aislamiento de red
        # ports:
        #     - "80:80"
        #     - "443:443"
        # networks:
        #     default:
        #         ipv4_address: 198.18.0.2

        # Configuración real de escalado horizontal: elimínalos, ya que se ejecutan en otros hosts.
        depends_on:
            server-pro-ha-1:
                condition: service_started
            server-pro-ha-2:
                condition: service_started
            server-pro-ha-3:
                condition: service_started

    # Configuración real de escalado horizontal: ejecuta este contenedor junto a server-pro-ha-1.
    # A partir de Server Pro 4.0.
    git-bridge:
        restart: always
        # La etiqueta debe coincidir con la etiqueta del contenedor `server-pro-ha-1`.
        image: quay.io/sharelatex/git-bridge:4.0.1
        volumes:
            # Configuración real de escalado horizontal: apunta /data/git-bridge a un ssd local dedicado.
            - ~/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"]

        # Configuración real de escalado horizontal: ejecútalo en el host 198.18.0.6 y expón el puerto
        # ports:
        #     - "8000:8000"
        networks:
            default:
                ipv4_address: 198.18.0.6

    # Configuración real de escalado horizontal: ejecuta este contenedor en un host separado.
    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:
            # Configuración real de escalado horizontal: conserva esta entrada.
            git-bridge:
                condition: service_started

            # Configuración real de escalado horizontal: elimina las siguientes, ya que se ejecutan en otros 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
            # Configuración real de escalado horizontal: proporciona tu propio dominio/nombre de aplicación.
            OVERLEAF_SITE_URL: 'https://overleaf.example.com'
            OVERLEAF_APP_NAME: Demo de escalado horizontal de Server Pro

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

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

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

            # S3
            # Configuración real de escalado horizontal: elige credenciales seguras.
            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
            # Solo es necesario en la instancia hermana de git-bridge
            V1_HISTORY_URL: "http://server-pro-ha-1:3100/api"
            # /git-bridge

            # Escalado horizontal
            # Configuración real de escalado horizontal: elige credenciales seguras.
            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'
            # Configuración real de escalado horizontal: IP de los balanceadores de carga
            TRUSTED_PROXY_IPS: 198.18.0.1,198.18.0.2
            # /Escalado horizontal

        # Configuración real de escalado horizontal: ejecuta en el host 198.18.1.1 y expone los puertos
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.1

    # Configuración real de escalado horizontal: ejecuta este contenedor en un host separado.
    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"

        # Configuración real de escalado horizontal: ejecuta en el host 198.18.1.2 y expone los puertos
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.2

    # Configuración real de escalado horizontal: ejecuta este contenedor en un host separado.
    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"

        # Configuración real de escalado horizontal: ejecuta en el host 198.18.1.3 y expone los puertos
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.3

    # Configuración real de escalado horizontal: ejecuta este contenedor en un host separado.
    minio:
        image: minio/minio:RELEASE.2023-05-18T00-05-36Z
        container_name: minio
        command: server /data
        volumes:
            # Configuración real de escalado horizontal: ejecuta minio con varios discos; consulta la documentación de minio.
            - ~/minio_data:/data
        environment:
            # Configuración real de escalado horizontal: elige credenciales seguras.
            MINIO_ROOT_USER: MINIO_ROOT_USER
            MINIO_ROOT_PASSWORD: MINIO_ROOT_PASSWORD

        # Configuración real de escalado horizontal: ejecuta en el host 198.18.0.5 y expone el puerto
        # ports:
        #     - "9000:9000"
        networks:
            default:
                ipv4_address: 198.18.0.5

    # Configuración real de escalado horizontal: ejecuta esta configuración una vez en un host separado.
    minio_setup:
        depends_on:
            - minio
        image: minio/mc:RELEASE.2023-05-18T16-59-00Z
        entrypoint: sh
        comando:
            - '-c'
            # Configuración real de escalado horizontal: elige credenciales seguras.
            - |
                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

                # Coloca el contenido de la política de la sección anterior en policy-filestore.json
                # Recordatorio: sustituye los nombres de los buckets según corresponda.
                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

    # Configuración real de escalado horizontal: ejecuta este contenedor en un host separado.
    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

        # Configuración real de escalado horizontal: ejecuta en el host 198.18.0.3 y expone el puerto
        # 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
        comando:
            - '-c'
            - |
                mongo 198.18.0.3 --eval "rs.initiate({ _id: \"overleaf\", members: [ { _id: 0, host: \"198.18.0.3:27017\" } ] })"

    # Configuración real de escalado horizontal: ejecuta este contenedor en un host separado.
    redis:
        restart: always
        image: redis:6.2
        container_name: redis
        expose:
            - 6379
        volumes:
            - ~/redis_data:/data

        # Configuración real de escalado horizontal: ejecuta en el host 198.18.0.4 y expone el puerto
        # ports:
        #     - "6379:6379"
        networks:
            default:
                ipv4_address: 198.18.0.4
```

</details>

#### Hardware

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

Las recomendaciones generales sobre [las especificaciones de hardware](/on-premises/es/primeros-pasos/requirements/hardware-requirements.md) para las instancias de Server Pro aplican.

#### Actualización de Server Pro

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

Las migraciones deben terminar antes de que se inicie la aplicación web real. Puedes comprobar los registros en busca de una entrada de `Migraciones finalizadas` o esperar hasta que la aplicación acepte tráfico.

El procedimiento de actualización es el siguiente:

1. Programar una ventana de mantenimiento
2. Detener todas las instancias de Server Pro
3. Realizar una copia de seguridad coherente como se describe en la [documentación](/on-premises/es/mantenimiento/data-and-backups.md#performing-a-consistent-backup)
4. Iniciar una sola instancia de Server Pro con la nueva versión
5. Validar que la nueva instancia funcione como se espera
6. Levantar las otras instancias con la nueva versión


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ayakaleaf-pro.ayaka.space/on-premises/es/mantenimiento/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.
