Installation
Recursos del sistema y ajuste
RAM/CPU mínimos y recomendados para un despliegue de QuoteNode, cómo funcionan los límites de contenedores, cómo ajustarlos y cómo evitar problemas de falta de memoria.
Recursos del sistema y ajuste
QuoteNode se ejecuta como un pequeño conjunto de contenedores Docker. Los archivos Compose incluyen límites de memoria ajustados para una VM de 4 GB de RAM y, por defecto, no limitan la CPU; cada límite se puede sobrescribir con una variable de entorno, de modo que pueda dimensionar la pila según su máquina.
Mínimo y recomendado
| Nivel | RAM del host | CPU del host | Notas |
|---|---|---|---|
| Mínimo | 4 GB | 2 núcleos | Perfil por defecto. Cómodo para un equipo pequeño (≈10 usuarios / ≈1 000 productos). |
| Recomendado | 8 GB | 4 núcleos | Margen para importaciones/exportaciones simultáneas y picos de PDF. |
| Con carga | 8–16 GB | 4–8 núcleos | ≈100 usuarios / ≈20 000 productos con operaciones masivas en paralelo. |
La pila es ligera en reposo: en reposo, toda la pila usa unos 1,5 GiB de RAM independientemente de cuántos datos haya en la base de datos (no hay caché de entidades en la JVM — los datos viven en PostgreSQL). La RAM escala con la concurrencia de operaciones masivas (importación/exportación/PDF), no con el número de usuarios o registros.
Cómo funcionan los límites de contenedores
mem_limit es un techo estricto, no una reserva. Un contenedor usa solo lo que realmente toca, hasta el límite; un contenedor que supera su límite es terminado por OOM. Un límite más alto no cuesta memoria — solo eleva el margen de seguridad.
El perfil por defecto suma unos 3 520 MiB de techos, lo que cabe en un host de 4 GB dejando ~575 MiB para el sistema operativo. Como el uso real en reposo es mucho menor (~1,5 GiB), los techos son margen para picos de carga, no el consumo esperado.
cpus también es un techo, pero la CPU es gratuita en reposo, así que por defecto no se fija ningún techo de CPU: cada servicio puede usar todos los núcleos del host y la CPU ociosa no cuesta nada. Si fija un techo *_CPUS, no supere el número de núcleos del host: Docker se niega a iniciar un contenedor cuyo cpus exceda los núcleos disponibles.
Límites por defecto por servicio (perfil 4 GB)
| Servicio | Memoria | CPU | Función |
|---|---|---|---|
| backend | 1536m | todos los núcleos | Servidor API/web (el heap de la JVM se dimensiona automáticamente al 70 % de esto) |
| postgres | 512m | todos los núcleos | Base de datos |
| backup-worker | 832m | todos los núcleos | Copias de seguridad programadas (pg_dump) |
| gotenberg | 448m | todos los núcleos | Renderizado de PDF con Chromium |
| frontend | 96m | todos los núcleos | Caddy sirviendo el build estático |
| caddy | 96m | todos los núcleos | Ingress TLS/proxy inverso — aumente CADDY_MEM_LIMIT con tráfico TLS intenso |
Ajustar la RAM
Cada límite es una variable de entorno opcional. Defínala donde su instalación guarda sus ajustes:
- Paquete de la versión (servidor, LAN, portátil o una carpeta en un NAS): el archivo
.envjunto adocker-compose.yml; después ejecutedocker compose up -d, que recrea los contenedores modificados. - Portainer: las variables de entorno del stack (
stack.env); después actualice el stack. - Coolify: su archivo Compose no fija límites por servicio, así que estas variables no tienen efecto allí.
# Example: an 8 GB machine with more concurrent load
BACKEND_MEM_LIMIT=3g
POSTGRES_MEM_LIMIT=1g
GOTENBERG_MEM_LIMIT=768m
El heap de Java del backend se dimensiona automáticamente al 70 % de BACKEND_MEM_LIMIT (mediante MaxRAMPercentage), por lo que subir el límite sube el heap automáticamente — sin flags de JVM que editar. Lo mismo aplica proporcionalmente al backup-worker (que usa el 45 %).
Variables disponibles: 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
No limite la CPU salvo que deba proteger otra carga en el mismo host. El único punto donde la CPU importa en la práctica es el arranque en frío: el backend y el worker basados en JVM arrancan un gran contexto de aplicación, lo cual está limitado por CPU. En un solo núcleo, un arranque en frío puede tardar minutos; con 2 o más núcleos está muy por debajo de un minuto. El período de gracia del healthcheck del worker ya tiene en cuenta los arranques lentos, así que una máquina limitada se recupera por sí sola, sin bucle de reinicios.
Evitar problemas de falta de memoria
- No reduzca
WORKER_MEM_LIMITpor debajo de ~768m. Una copia de seguridad (pg_dump+tar+gzip+ la JVM) alcanza un pico de unos 607 MiB; con menos margen puede terminarse a mitad de la copia. - En una VM de 2 GB, el perfil por defecto es demasiado grande — baje los límites (p. ej.
BACKEND_MEM_LIMIT=768m,POSTGRES_MEM_LIMIT=384m) para que la suma quede por debajo de la RAM física. El heap del backend sigue el límite automáticamente. - Vigile el host, no solo los contenedores. Si el host ejecuta otras cargas, cuente también su memoria — Docker solo impone techos por contenedor, no el uso total del host.
- Un contenedor que se reinicia repetidamente con código de salida 137 indica un kill por OOM; aumente el
*_MEM_LIMITde ese servicio.