> 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/pt/manutencao/horizontal-scaling.md).

# Escalabilidade horizontal

A partir da versão 3.5.6, o Server Pro suporta escalonamento horizontal.

Este documento lista os requisitos técnicos e fornece diretrizes para executar o Server Pro em mais de um nó.

{% hint style="danger" %}
A partir do Server CE/Server Pro `5.0.3` as variáveis de ambiente foram renomeadas de `SHARELATEX_*` para `OVERLEAF_*`.

Se você estiver usando uma `4.x` versão (ou anterior), certifique-se de que as variáveis estejam prefixadas adequadamente (por exemplo, `SHARELATEX_SITE_URL` em vez de `OVERLEAF_SITE_URL`)
{% endhint %}

Configurar o escalonamento horizontal exige uma quantidade significativa de esforço. Recomendamos considerar o escalonamento horizontal **apenas** ao atingir uma certa escala. Como exemplo, uma instalação do Server Pro para 1.000 usuários no total foi configurada com sucesso usando um único servidor provisionado com dois processadores de 4 núcleos e 32 GB de memória do sistema. Consulte a [requisitos de hardware](/on-premises/pt/primeiros-passos/requirements/hardware-requirements.md) documentação para recomendações.

Uma implantação do Server Pro com escalonamento horizontal envolve um conjunto de componentes externos, como um balanceador de carga e um backend de armazenamento compatível com S3.

Podemos ajudar a diagnosticar erros nos contêineres do Server Pro que possam ser resultado de configuração incorreta e fornecer orientações gerais com base neste documento. Infelizmente, não conseguimos fornecer assistência para configurar aplicações/sistemas de terceiros.

A resolução de problemas técnicos específicos do seu hardware/software para fornecer os componentes externos não está coberta pelos nossos termos de suporte.

### Requisitos

#### Armazenamento central de dados externo

O armazenamento de dados no Server Pro pode ser dividido em quatro repositórios de dados:

* **MongoDB**

  * A maior parte dos dados é persistida no MongoDB.
  * Suportamos uma instância local ou uma instância externa, como [MongoDB](https://www.mongodb.com/atlas) Atlas (um serviço MongoDB totalmente gerenciado que é executado dentro da infraestrutura da AWS).<br>

  **Nota:** Infelizmente, no momento não há suporte oficial para bancos de dados compatíveis com MongoDB, como CosmoDB/DocumentDB, pois não testamos o Server Pro com eles. Embora a implantação do Server Pro com bancos de dados compatíveis **pode** ser possível, só damos suporte oficial a implantações usando MongoDB.<br>
* **Redis**

  * O Redis armazena dados temporários, como atualizações pendentes de documentos antes de serem gravadas no MongoDB.
  * O Redis é usado para comunicar atualizações de documentos entre diferentes serviços e notificar o editor sobre mudanças de estado em um determinado projeto.
  * O Redis é usado para armazenar as sessões de usuário.
  * Suportamos uma instância local ou uma instância externa.<br>

  **Nota:** Infelizmente, no momento não há suporte oficial para armazenamentos de chave/valor compatíveis com Redis, como KeyDB/Valkey, pois não testamos o Server Pro com eles. Embora a implantação do Server Pro com armazenamentos compatíveis **pode** ser possível, só damos suporte oficial a implantações usando Redis.<br>
* **Arquivos do projeto e arquivos de histórico**

  * Os arquivos de projeto não editáveis são armazenados fora do MongoDB.

    O novo sistema de histórico de projetos (Server Pro 3.5 em diante) também armazena o histórico fora do MongoDB.
  * Para instâncias únicas pequenas, suportamos um sistema de arquivos local (que pode ser apoiado por um SSD local, NFS ou EBS) ou um [sistema de armazenamento de dados compatível com S3](/on-premises/pt/configuracao/overleaf-toolkit/s3.md).
  * Para escalonamento horizontal, nós **apenas** suportamos sistemas de armazenamento de dados compatíveis com S3.<br>

  **Importante:** NFS/Amazon EFS/Amazon EBS são **não** suportados para escalonamento horizontal. Consulte a [armazenamento de hardware](/on-premises/pt/primeiros-passos/requirements/hardware-requirements.md#storage) seção de requisitos sobre escalonamento de armazenamento no Server Pro para mais detalhes.
* **Arquivos efêmeros**
  * As compilações LaTeX precisam ser executadas em discos locais rápidos para desempenho ideal. O resultado da compilação não precisa ser persistido nem copiado em backup.
  * O buffer de novos envios de arquivos e a criação de arquivos zip do projeto também se beneficiam do uso de um disco local.

{% hint style="danger" %}
Recomendamos fortemente o uso de um disco local. O uso de qualquer tipo de disco em rede (como NFS ou EBS) pode resultar em erros de compilação inesperados e outros problemas de desempenho.
{% endhint %}

#### **Git-bridge**

{% hint style="info" %}
O Git-bridge está disponível no Server Pro a partir da versão 4.0.1.
{% endhint %}

Os repositórios git são armazenados localmente em disco. Não há opções de replicação disponíveis. O Git-bridge deve ser executado como uma **instância única**. Para desempenho ideal, recomendamos o uso de um disco local para os dados do git-bridge. O disco de dados do git-bridge deve ser copiado regularmente em backup.

Para o armazenamento de dados com escalonamento horizontal, você precisa de:

* uma instância central do MongoDB acessível a partir de todas as instâncias do Server Pro
* uma instância central do Redis acessível a partir de todas as instâncias do Server Pro
* um backend de armazenamento compatível com S3 central para arquivos de projeto e histórico
* um disco local em cada instância para arquivos efêmeros
* um disco local na instância que hospeda o contêiner git-bridge para os dados do git-bridge

#### Requisitos do balanceador de carga

* **Roteamento persistente**, por exemplo usando um cookie

  Este requisito decorre destes componentes:

  * A capacidade de edição em tempo real no Server Pro usa WebSockets com um fallback para sondagem XHR. Cada sessão de edição tem estado local no lado do servidor e as solicitações de uma determinada sessão de edição sempre precisam ser roteadas para a mesma instância do Server Pro. O recurso de colaboração usa Redis [Pub/Sub](https://redis.io/docs/latest/develop/interact/pubsub/) para compartilhar atualizações entre várias instâncias do Server Pro.
  * A compilação LaTeX mantém a saída e o cache de compilação localmente para desempenho ideal. Ao emitir uma solicitação de compilação para uma instância do Server Pro, as seguintes solicitações de download de PDF/log precisam ser roteadas para a mesma instância do Server Pro.
* **Tempos limite de solicitação longos** para suportar a compilação de grandes documentos LaTeX
* **Suporte a WebSocket** para desempenho ideal
* **Tamanho da carga útil POST de 50 MB**
* **Tempo limite keep-alive** deve ser inferior ao tempo limite keep-alive do Server Pro

  O tempo limite keep-alive no Server Pro pode ser configurado usando a variável de ambiente `NGINX_KEEPALIVE_TIMEOUT`. O valor padrão é 65 s.

  Com o padrão, um tempo limite keep-alive de 60 s no balanceador de carga funciona.

  Com `NGINX_KEEPALIVE_TIMEOUT=120`, o balanceador de carga poderia usar 115 s.
* **IPs dos clientes**

  Defina o cabeçalho da solicitação `X-Forwarded-For` com o IP do cliente.
* Quando **terminação de SSL**

  O balanceador de carga precisa adicionar o cabeçalho da solicitação `X-Forwarded-Proto: https`.

<details>

<summary>Exemplo de configuração do HAProxy</summary>

```
global
  group haproxy
  user haproxy

  # Logs detalhados
  log stdout format raw local0 debug

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

  # Logs detalhados
  log                     global
  option                  httplog

  # Redirecionar para um backend diferente se o persistente estiver fora do ar
  option                  redispatch 1
  # Essas tentativas são para erros de conexão TCP, não para respostas HTTP status 500
  retries                 3

  # Sessão persistente por 24h de inatividade -- a saída da compilação é excluída após 24h
  cookie                  server-pro-ha insert maxidle 24h

  # Tentar conectar a qualquer backend por 1 min, depois retornar 503
  timeout queue           1m
  # Dar às instâncias do Server Pro 15 s para iniciar
  timeout connect         15s

  # Abortar solicitações de clientes muito lentos (permitir 1 min de inatividade ao ler uma solicitação)
  timeout client          1m

  # Permitir compilações lentas -- o limite fixo no clsi é 10 min
  timeout server          10m

  # Desconectar o editor após 23 h -- 1 h antes do último uso de ontem
  timeout tunnel          23h

  # Observação: o comportamento de keepalive no haproxy funciona muito bem com a configuração padrão de keepalive no Server Pro.
  #       O Haproxy está limpando conexões em segundo plano e irá redistribuir as solicitações quando necessário.

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

  # Diga à aplicação que estamos atrás de https
  http-request set-header X-Forwarded-Proto https

  # Diga à aplicação o IP real do cliente
  option forwardfor

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

  # Roteie o tráfego git para o contêiner irmão do git-bridge
  use-server server-pro-ha-1 if { path_beg /git/ }

  # Depuração
  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>

#### Configuração do Server Pro

**Segredos**

As instâncias do Server Pro precisam concordar com segredos compartilhados:

* `WEB_API_PASSWORD` (autenticação da API web)
* `STAGING_PASSWORD` e `V1_HISTORY_PASSWORD` mesmo valor (autenticação do histórico)
* `CRYPTO_RANDOM` (para o cookie de sessão)
* `OT_JWT_AUTH_KEY` (autenticação do histórico)

Todos esses segredos precisam ser configurados com seu próprio valor exclusivo e compartilhados entre as instâncias.

Quando não configuradas e as solicitações dos usuários forem roteadas para diferentes instâncias do Server Pro, suas solicitações falharão nas verificações de autenticação e eles serão redirecionados frequentemente para a página de login ou suas ações na interface falharão de maneiras inesperadas.

Quando não configurado, o Server Pro usa um novo valor aleatório para cada segredo com base em 32 bytes aleatórios de `/dev/urandom` (256 bits aleatórios).

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

Aponte `OVERLEAF_MONGO_URL` (`SHARELATEX_MONGO_URL` para versões `4.x` e anteriores) na instância central do MongoDB.

**Redis**

Aponte `OVERLEAF_REDIS_HOST` (`SHARELATEX_REDIS_HOST` para versões `4.x` e anteriores) e `REDIS_HOST` na instância central do Redis.

**Armazenamento S3 compatível para arquivos de projeto e histórico**

Consulte a documentação sobre [armazenamento compatível com S3](/on-premises/pt/configuracao/overleaf-toolkit/s3.md) para mais detalhes.

**Arquivos efêmeros**

O bind mount padrão de um SSD local para `/var/lib/overleaf` (`/var/lib/sharelatex` para versões `4.x` e anteriores) será suficiente. Certifique-se de apontar `SANDBOXED_COMPILES_HOST_DIR` para o ponto de montagem no host.

{% hint style="danger" %}
Recomendamos fortemente o uso de um disco local. O uso de qualquer tipo de disco em rede (como NFS ou EBS) pode resultar em erros de compilação inesperados e outros problemas de desempenho.
{% endhint %}

**Configuração de proxy**

* Defina `OVERLEAF_BEHIND_PROXY=true` (`SHARELATEX_BEHIND_PROXY` para versões `4.x` e anteriores) para IPs de clientes precisos.
* Defina `TRUSTED_PROXY_IPS` para o IP do balanceador de carga (vários CIDRs podem ser especificados, separados por vírgula).

**Integração do git-bridge**

{% hint style="info" %}
O Git-bridge está disponível no Server Pro a partir da versão 4.0.1.
{% endhint %}

O contêiner git-bridge precisa de um contêiner irmão do Server Pro para lidar com solicitações git recebidas. Esse contêiner irmão também pode atender ao tráfego normal de usuários. Na configuração de exemplo, a primeira instância atua como contêiner irmão do git-bridge, mas qualquer instância poderia realmente cumprir essa função.

Por que precisamos designar um contêiner do Server Pro como irmão do git-bridge? O Server Pro fornece URLs de download do serviço de histórico para o git-bridge. Precisamos configurar essas URLs de histórico para que sejam acessíveis a partir do contêiner git-bridge.

Configuração do contêiner Server Pro:

* Defina `GIT_BRIDGE_ENABLED` para `'true'`
* Defina `GIT_BRIDGE_HOST` para `<nome do contêiner git-bridge>` por exemplo `git-bridge`
* Defina `GIT_BRIDGE_PORT` para `8000`
* Defina `V1_HISTORY_URL` para `http://<nome do contêiner irmão do server-pro>:3100/api`.

  Observação: isso é necessário apenas no contêiner irmão para o contêiner git-bridge. As outras instâncias podem usar uma URL localhost, que é o padrão.

Configuração do contêiner git-bridge:

* Defina `GIT_BRIDGE_API_BASE_URL` para `http://<nome do contêiner irmão do server-pro>/api/v0`, por exemplo `http://server-pro-ha-1/api/v0`
* Defina `GIT_BRIDGE_OAUTH2_SERVER` para `http://<nome do contêiner irmão do server-pro>`, por exemplo `http://server-pro-ha-1`
* Defina `GIT_BRIDGE_POSTBACK_BASE_URL` para `http://<nome do contêiner git-bridge>:8000`, por exemplo `http://git-bridge:8000`
* Defina `GIT_BRIDGE_ROOT_DIR` para o disco de dados git-bridge montado no host, por exemplo `/data/git-bridge`

<details>

<summary>Exemplo de configuração do docker-compose.yml</summary>

A configuração a seguir mostra uma configuração autônoma. Para a demonstração funcionar, você precisa fornecer uma chave/certificado SSL válido e ajustar o `OVERLEAF_SITE_URL` (`SHARELATEX_SITE_URL` para versões `4.x` e anteriores). Para uma configuração real, você deve substituir os segredos fictícios por segredos reais, conforme indicado inline. Para uma configuração real, você precisa mover os contêineres individuais para nós dedicados e ajustar os endereços IP à sua configuração de rede local.

```yaml
version: '2.2'

# Configuração real de escalonamento horizontal: escolha sua própria rede e substitua os IPs na configuração.
networks:
    default:
        ipam:
            config:
                # Esta sub-rede faz parte de uma sub-rede reservada usada para benchmarking
                # https://tools.ietf.org/html/rfc2544
                # A sub-rede completa é 198.18.0.0/15
                # Use 198.18.0.0/24 para lb e dbs
                # Use 198.18.1.0/24 para server-pro
                # Use 198.18.0.128/25 para contêiner efêmero
                - gateway: 198.18.0.1
                  ip_range: 198.18.0.128/25
                  subnet: 198.18.0.0/23

services:
    # Configuração real de escalonamento horizontal: execute o haproxy fora do Docker em um 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": use a rede do host para evitar a sobrecarga do docker-proxy
        network_mode: host

        # Alternativa a "network_mode: host": use docker-proxy para isolamento de rede
        # ports:
        #     - "80:80"
        #     - "443:443"
        # networks:
        #     default:
        #         ipv4_address: 198.18.0.2

        # Configuração real de escalonamento horizontal: remova estes, pois eles são executados em outros hosts.
        depends_on:
            server-pro-ha-1:
                condition: service_started
            server-pro-ha-2:
                condition: service_started
            server-pro-ha-3:
                condition: service_started

    # Configuração real de escalonamento horizontal: execute este contêiner ao lado do server-pro-ha-1.
    # Para o Server Pro 4.0 em diante.
    git-bridge:
        restart: always
        # A tag deve corresponder à tag do contêiner `server-pro-ha-1`.
        image: quay.io/sharelatex/git-bridge:4.0.1
        volumes:
            # Configuração real de escalonamento horizontal: aponte /data/git-bridge para um 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"]

        # Configuração real de escalonamento horizontal: execute no host 198.18.0.6 e exponha a porta
        # ports:
        #     - "8000:8000"
        networks:
            default:
                ipv4_address: 198.18.0.6

    # Configuração real de escalonamento horizontal: execute este contêiner em um 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:
            # Configuração real de escalonamento horizontal: mantenha esta entrada.
            git-bridge:
                condition: service_started

            # Configuração real de escalonamento horizontal: remova as entradas abaixo, pois elas são executadas em outros 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
            # Configuração real de escalonamento horizontal: forneça seu próprio domínio/nome do aplicativo.
            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
            # Configuração real de escalonamento horizontal: escolha credenciais 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
            # Necessário apenas na instância irmã do git-bridge
            V1_HISTORY_URL: "http://server-pro-ha-1:3100/api"
            # /git-bridge

            # Escalabilidade horizontal
            # Configuração real de escalonamento horizontal: escolha credenciais 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'
            # Configuração real de escalabilidade horizontal: IPs dos balanceadores de carga
            TRUSTED_PROXY_IPS: 198.18.0.1,198.18.0.2
            # /Escalabilidade horizontal

        # Configuração real de escalabilidade horizontal: execute no host 198.18.1.1 e exponha portas
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.1

    # Configuração real de escalonamento horizontal: execute este contêiner em um 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"

        # Configuração real de escalabilidade horizontal: execute no host 198.18.1.2 e exponha portas
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.2

    # Configuração real de escalonamento horizontal: execute este contêiner em um 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"

        # Configuração real de escalabilidade horizontal: execute no host 198.18.1.3 e exponha portas
        # ports:
        #     - "80:80"
        networks:
            default:
                ipv4_address: 198.18.1.3

    # Configuração real de escalonamento horizontal: execute este contêiner em um host separado.
    minio:
        image: minio/minio:RELEASE.2023-05-18T00-05-36Z
        container_name: minio
        command: server /data
        volumes:
            # Configuração real de escalabilidade horizontal: execute o minio com vários discos, veja a documentação do minio.
            - ~/minio_data:/data
        environment:
            # Configuração real de escalonamento horizontal: escolha credenciais seguras.
            MINIO_ROOT_USER: MINIO_ROOT_USER
            MINIO_ROOT_PASSWORD: MINIO_ROOT_PASSWORD

        # Configuração real de escalabilidade horizontal: execute no host 198.18.0.5 e exponha a porta
        # ports:
        #     - "9000:9000"
        networks:
            default:
                ipv4_address: 198.18.0.5

    # Configuração real de escalabilidade horizontal: execute esta configuração uma vez em um host separado.
    minio_setup:
        depends_on:
            - minio
        image: minio/mc:RELEASE.2023-05-18T16-59-00Z
        entrypoint: sh
        comando:
            - '-c'
            # Configuração real de escalonamento horizontal: escolha credenciais 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

                # Coloque o conteúdo da política da seção anterior em policy-filestore.json
                # Lembrete: substitua os nomes dos buckets de acordo.
                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

    # Configuração real de escalonamento horizontal: execute este contêiner em um 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

        # Configuração real de escalabilidade horizontal: execute no host 198.18.0.3 e exponha a porta
        # 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\" } ] })"

    # Configuração real de escalonamento horizontal: execute este contêiner em um host separado.
    redis:
        restart: always
        image: redis:6.2
        container_name: redis
        expose:
            - 6379
        volumes:
            - ~/redis_data:/data

        # Configuração real de escalabilidade horizontal: execute no host 198.18.0.4 e exponha a porta
        # ports:
        #     - "6379:6379"
        networks:
            default:
                ipv4_address: 198.18.0.4
```

</details>

#### Hardware

Recomendamos usar as mesmas especificações de hardware para todas as instâncias do Server Pro que participam da escalabilidade horizontal.

As recomendações gerais sobre [especificações de hardware](/on-premises/pt/primeiros-passos/requirements/hardware-requirements.md) para instâncias do Server Pro aplicam-se.

#### Atualizando o Server Pro

Como parte do processo de atualização, o Server Pro executa automaticamente migrações de banco de dados. Essas migrações são **não** concebidas para serem executadas por várias instâncias em paralelo.

As migrações precisam terminar antes que a aplicação web real seja iniciada. Você pode verificar nos logs uma entrada de `Migrações concluídas` ou aguardar até que a aplicação aceite tráfego.

O procedimento de atualização é o seguinte:

1. Agendar uma janela de manutenção
2. Parar todas as instâncias do Server Pro
3. Fazer uma cópia de segurança consistente conforme descrito em [documentação](/on-premises/pt/manutencao/data-and-backups.md#performing-a-consistent-backup)
4. Iniciar uma única instância do Server Pro com a nova versão
5. Validar que a nova instância está funcionando como esperado
6. Subir as outras instâncias com a nova versão


---

# 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/pt/manutencao/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.
