Installation
Recursos do sistema e otimização
RAM/CPU mínimos e recomendados para uma implantação do QuoteNode, como funcionam os limites de contêineres, como ajustá-los e como evitar problemas de falta de memória.
Recursos do sistema e otimização
O QuoteNode é executado como um pequeno conjunto de contêineres Docker. Os ficheiros Compose vêm com limites de memória e CPU ajustados para uma VM de 4 GB de RAM, e cada limite pode ser substituído por uma variável de ambiente, permitindo dimensionar a pilha conforme a sua máquina.
Mínimo e recomendado
| Nível | RAM do host | CPU do host | Notas |
|---|---|---|---|
| Mínimo | 4 GB | 2 núcleos | Perfil padrão. Confortável para uma equipa pequena (≈10 utilizadores / ≈1 000 produtos). |
| Recomendado | 8 GB | 4 núcleos | Margem para importações/exportações simultâneas e picos de PDF. |
| Sob carga | 8–16 GB | 4–8 núcleos | ≈100 utilizadores / ≈20 000 produtos com operações em massa em paralelo. |
A pilha é leve em repouso: em repouso, toda a pilha usa cerca de 1,5 GiB de RAM independentemente da quantidade de dados na base de dados (não há cache de entidades na JVM — os dados vivem no PostgreSQL). A RAM escala com a concorrência de operações em massa (importação/exportação/PDF), não com o número de utilizadores ou registos.
Como funcionam os limites de contêineres
mem_limit é um teto rígido, não uma reserva. Um contêiner usa apenas o que realmente toca, até ao limite; um contêiner que excede o seu limite é terminado por OOM. Um limite mais alto não custa memória — apenas eleva a fronteira de segurança.
O perfil padrão soma cerca de 3 520 MiB de tetos, o que cabe num host de 4 GB deixando ~575 MiB para o sistema operativo. Como o uso real em repouso é muito menor (~1,5 GiB), os tetos são margem para picos de carga, não o consumo esperado.
cpus também é um teto, mas a CPU é gratuita em repouso — um teto de CPU generoso não custa nada em repouso e permite que um serviço use núcleos quando precisa. Um valor cpus superior ao número de núcleos do host significa simplesmente «usar todos os núcleos disponíveis», por isso os valores padrão são seguros numa VM de 1–2 núcleos.
Limites padrão por serviço (perfil 4 GB)
| Serviço | Memória | CPU | Função |
|---|---|---|---|
| backend | 1536m | 4.0 | Servidor API/web (o heap da JVM dimensiona-se automaticamente para 70 % disto) |
| postgres | 512m | 4.0 | Base de dados |
| backup-worker | 832m | 2.0 | Backups agendados (pg_dump) |
| gotenberg | 448m | 2.0 | Renderização de PDF com Chromium |
| frontend | 96m | 2.0 | Caddy a servir o build estático |
| caddy | 96m | 2.0 | Ingress TLS/proxy reverso — aumente CADDY_MEM_LIMIT com tráfego TLS intenso |
Ajustar a RAM
Cada limite é uma variável de ambiente opcional. Defina-a no seu .env.prod para substituir o valor padrão:
# Exemplo: uma máquina de 8 GB com mais carga simultânea
BACKEND_MEM_LIMIT=3g
POSTGRES_MEM_LIMIT=1g
GOTENBERG_MEM_LIMIT=768m
O heap Java do backend dimensiona-se automaticamente para 70 % de BACKEND_MEM_LIMIT (via MaxRAMPercentage), por isso aumentar o limite aumenta o heap automaticamente — sem flags da JVM para editar. O mesmo se aplica proporcionalmente ao backup-worker (que usa 45 %).
Variáveis disponíveis: BACKEND_MEM_LIMIT, BACKEND_CPUS, POSTGRES_MEM_LIMIT, POSTGRES_CPUS, WORKER_MEM_LIMIT, WORKER_CPUS, GOTENBERG_MEM_LIMIT, GOTENBERG_CPUS, FRONTEND_MEM_LIMIT, FRONTEND_CPUS, CADDY_MEM_LIMIT, CADDY_CPUS.
CPU
Deixe os valores de CPU padrão generosos. O único ponto onde a CPU importa na prática é o arranque a frio: o backend e o worker baseados em JVM arrancam um grande contexto de aplicação, o que é limitado pela CPU. Num único núcleo, um arranque a frio pode demorar minutos; com 2 ou mais núcleos fica bem abaixo de um minuto. O período de tolerância do healthcheck do worker já contempla arranques lentos, por isso uma máquina limitada recupera sozinha, sem ciclo de reinícios.
Evitar problemas de falta de memória
- Não reduza
WORKER_MEM_LIMITabaixo de ~768m. Um backup (pg_dump+tar+gzip+ a JVM) atinge um pico de cerca de 607 MiB; com menos margem pode ser terminado a meio do backup. - Numa VM de 2 GB, o perfil padrão é demasiado grande — baixe os limites (p. ex.
BACKEND_MEM_LIMIT=768m,POSTGRES_MEM_LIMIT=384m) para que a soma fique abaixo da RAM física. O heap do backend segue o limite automaticamente. - Vigie o host, não apenas os contêineres. Se o host executa outras cargas, conte também a memória delas — o Docker só impõe tetos por contêiner, não o uso total do host.
- Um contêiner que reinicia repetidamente com código de saída 137 indica um kill por OOM; aumente o
*_MEM_LIMITdesse serviço.