Installation
Recursos do sistema e otimização
RAM/CPU mínimos e recomendados para uma implantação do QuoteNode, como funcionam os limites de contentores, 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 contentores Docker. Os ficheiros Compose vêm com limites de memória ajustados para uma VM de 4 GB de RAM, sem limite de CPU por omissão, 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 contentores
mem_limit é um teto rígido, não uma reserva. Um contentor usa apenas o que realmente toca, até ao limite; um contentor 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, por isso nenhum teto de CPU é definido por omissão: cada serviço pode usar todos os núcleos do host e a CPU inativa não custa nada. Se definir um teto *_CPUS, não ultrapasse o número de núcleos do host — o Docker recusa iniciar um contentor cujo cpus exceda os núcleos disponíveis.
Limites padrão por serviço (perfil 4 GB)
| Serviço | Memória | CPU | Função |
|---|---|---|---|
| backend | 1536m | todos os núcleos | Servidor API/web (o heap da JVM dimensiona-se automaticamente para 70 % disto) |
| postgres | 512m | todos os núcleos | Base de dados |
| backup-worker | 832m | todos os núcleos | Backups agendados (pg_dump) |
| gotenberg | 448m | todos os núcleos | Renderização de PDF com Chromium |
| frontend | 96m | todos os núcleos | Caddy a servir o build estático |
| caddy | 96m | todos os núcleos | 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 onde a sua instalação guarda as definições:
- Pacote da versão (servidor, LAN, portátil ou uma pasta num NAS): o ficheiro
.envao lado dodocker-compose.yml; depois executedocker compose up -d, que recria os contentores alterados. - Portainer: as variáveis de ambiente da stack (
stack.env); depois atualize a stack. - Coolify: o respetivo ficheiro Compose não define limites por serviço, pelo que estas variáveis não têm efeito aí.
# Example: an 8 GB machine with more concurrent load
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
Não limite a CPU, a menos que precise de proteger outra carga no mesmo host. 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 contentores. Se o host executa outras cargas, conte também a memória delas — o Docker só impõe tetos por contentor, não o uso total do host.
- Um contentor que reinicia repetidamente com código de saída 137 indica um kill por OOM; aumente o
*_MEM_LIMITdesse serviço.