Configuración de Docker Compose para n8n Workflow Automation + PostgreSQL
Cuándo usar esta combinación
Utiliza esta arquitectura al desplegar n8n en entornos de producción que manejan cargas de trabajo críticas o flujos concurrentes de alto volumen. Por defecto, n8n utiliza SQLite, el cual sufre bloqueos de concurrencia y no escala. PostgreSQL desacopla la capa de persistencia del motor de ejecución, garantizando transacciones ACID, integridad referencial y facilitando estrategias empresariales de respaldo (RTO/RPO). Es indispensable cuando se implementan ejecuciones basadas en webhooks masivos, arquitecturas con múltiples workers o integraciones que requieren tolerancia a fallos.
Configuración de Docker Compose (docker-compose.yml)
version: '3.8'
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_storage:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- WEBHOOK_URL=${WEBHOOK_URL}
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
volumes:
- n8n_storage:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_storage:
n8n_storage:
Variables de entorno críticas para producción
N8N_ENCRYPTION_KEY: Clave criptográfica utilizada para cifrar las credenciales y tokens almacenados en la base de datos. Si no se fija de forma estática y segura, cualquier recreación del contenedor provocará la pérdida irrecuperable de acceso a las credenciales configuradas.POSTGRES_PASSWORD(y su contraparteDB_POSTGRESDB_PASSWORD): Contraseña de acceso a la base de datos PostgreSQL. Debe ser una cadena aleatoria de alta entropía (mínimo 32 caracteres) para evitar accesos no autorizados a la capa de datos.WEBHOOK_URL: URL pública canónica (ej.https://n8n.tuempresa.com/). Si no se define correctamente detrás de un Reverse Proxy/Ingress (Nginx, Traefik), los webhooks generarán URLs internas incompatibles con servicios externos y fallarán las llamadas de retorno.
Consejo de Rendimiento y Seguridad DevOps
Implementa poda de datos de ejecución y no expongas PostgreSQL.
El cuello de botella clásico de n8n es el crecimiento desmedido de la tabla execution_entity, que satura el I/O de PostgreSQL. Activa obligatoriamente la limpieza automática con EXECUTIONS_DATA_PRUNE=true y un tiempo de vida corto (EXECUTIONS_DATA_MAX_AGE=72 horas para éxito, almacenando solo fallos si es necesario).
A nivel de seguridad de red, nunca expongas el puerto 5432 de PostgreSQL al host; la comunicación entre n8n y la base de datos debe ser estrictamente interna mediante la red por defecto creada por Docker Compose. Coloca n8n detrás de un reverse proxy con terminación TLS y rate-limiting estricto sobre el endpoint /webhook/*.
Checklist de Seguridad antes de desplegar
- Cambiar las contraseñas por defecto en el archivo .env
- Mapear volúmenes persistentes en el VPS
- Configurar las reglas de firewall para los puertos requeridos