YAML / Intermedio / 6 min
Docker Compose: n8n con HTTPS en VPS
docker-compose.yml para desplegar n8n con Traefik, PostgreSQL y certificados SSL automáticos.
Despliega tu propia instancia de n8n con HTTPS en un VPS usando Traefik como reverse proxy, PostgreSQL como base de datos y certificados automáticos con Let's Encrypt.
Esta configuración es práctica para agencias y consultores que necesitan automatizaciones privadas sin depender de una instancia SaaS compartida.
Guía de Implementación Paso a Paso
- Usa un VPS con Ubuntu 22+, Docker y Docker Compose instalados.
- Apunta el DNS de
n8n.tudominio.comal servidor. - Instala Docker si aún no existe.
BASH
curl -fsSL https://get.docker.com | sh
- Crea la estructura de directorios.
BASH
mkdir -p ~/n8n-stack/traefik
cd ~/n8n-stack
touch traefik/acme.json
chmod 600 traefik/acme.json
- Crea
.env.
ENV
N8N_DOMAIN=n8n.tudominio.com
N8N_ENCRYPTION_KEY=genera_una_clave_random_de_32chars
POSTGRES_PASSWORD=otra_clave_muy_segura
LETSENCRYPT_EMAIL=tu@email.com
- Copia el
docker-compose.ymly despliega.
BASH
docker compose up -d
YAML
# docker-compose.yml
# KODFLUX - n8n Self-Hosted con Traefik + PostgreSQL + HTTPS automático
#
# Antes de levantar:
# mkdir -p traefik
# touch traefik/acme.json
# chmod 600 traefik/acme.json
version: "3.8"
services:
traefik:
image: traefik:v3.2
container_name: traefik
restart: unless-stopped
command:
- "--api.dashboard=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL}"
- "--certificatesresolvers.le.acme.storage=/certs/acme.json"
- "--certificatesresolvers.le.acme.tlschallenge=true"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/acme.json:/certs/acme.json
networks:
- n8n-network
postgres:
image: postgres:16-alpine
container_name: n8n-postgres
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- n8n-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_HOST: ${N8N_DOMAIN}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: https://${N8N_DOMAIN}/
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
GENERIC_TIMEZONE: America/Lima
TZ: America/Lima
NODE_ENV: production
EXECUTIONS_DATA_PRUNE: "true"
EXECUTIONS_DATA_MAX_AGE: 720
volumes:
- n8n-data:/home/node/.n8n
networks:
- n8n-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`${N8N_DOMAIN}`)"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.routers.n8n.tls.certresolver=le"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
- "traefik.http.middlewares.n8n-headers.headers.sslRedirect=true"
- "traefik.http.middlewares.n8n-headers.headers.forceSTSHeader=true"
- "traefik.http.middlewares.n8n-headers.headers.stsSeconds=31536000"
volumes:
postgres-data:
n8n-data:
networks:
n8n-network:
driver: bridge
Prompt para Codex
TEXT
Crea un archivo docker-compose.yml para desplegar n8n en un VPS con las siguientes características:
Servicios requeridos:
1. Traefik v3 como reverse proxy:
- Certificados SSL automáticos con Let's Encrypt (TLS challenge)
- Redirección HTTP → HTTPS global
- Sin dashboard expuesto al exterior
2. PostgreSQL 16-alpine como base de datos:
- Con healthcheck (pg_isready)
- Credenciales desde variables de entorno
3. n8n (imagen oficial docker.n8n.io/n8nio/n8n:latest):
- depends_on postgres con condition: service_healthy
- Configuración completa: DB_TYPE, host, puerto, usuario, contraseña
- N8N_HOST, WEBHOOK_URL, N8N_ENCRYPTION_KEY desde variables de entorno
- Timezone: America/Lima
- EXECUTIONS_DATA_PRUNE=true con 30 días máximo
- Labels de Traefik para routing y HTTPS
- Labels de headers de seguridad (HSTS)
Variables de entorno (usando ${VAR}):
- N8N_DOMAIN, N8N_ENCRYPTION_KEY, POSTGRES_PASSWORD, LETSENCRYPT_EMAIL
Red interna bridge compartida entre los 3 servicios.
Volúmenes nombrados para postgres y n8n.
Incluir instrucciones en comentarios sobre cómo crear el archivo acme.json con permisos 600.