Guía Definitiva de Instalación de n8n: Self-Hosted con Docker Compose (2026)
📋 Resumen Ejecutivo
Esta guía te permite instalar n8n (plataforma open source de automatización de flujos de trabajo) en tu propio servidor usando Docker Compose. Incluye configuración de PostgreSQL, SSL/HTTPS, autenticación básica y todas las mejores prácticas para producción.
⚡ ¿Qué lograrás al final?
- ✅ Instalar n8n con Docker Compose en un VPS o servidor Linux
- ✅ Configurar PostgreSQL como base de datos persistente
- ✅ Establecer HTTPS con Let's Encrypt (Caddy/Nginx)
- ✅ Habilitar autenticación básica para seguridad
- ✅ Configurar variables críticas:
N8N_ENCRYPTION_KEY,N8N_WEBHOOK_URL - ✅ Implementar copias de seguridad automáticas
- ✅ Actualizar sin perder datos
🎯 Requisitos Previos
Hardware Mínimo Recomendado
| Uso | vCPU | RAM | Almacenamiento | Coste mensual |
|---|---|---|---|---|
| Testing básico | 1 | 2 GB | 20 GB SSD | $5-7 (Cherry Servers) |
| Producción pequeña | 2-4 | 4-8 GB | 40-80 GB NVMe | $10-20 (Hetzner CX22, Sliplane) |
⚠️ Nota: n8n recomienda mínimo 4 GB RAM y 2 vCPUs para el setup actual con runner container.
Software Requerido
# Verificar Docker
docker --version
# Salida esperada: Docker Engine 20.10+
# Verificar Docker Compose
docker compose version
# Nota: espacio entre "docker" y "compose" (sin guion)
Sistema Operativo
- Linux: Ubuntu 22.04 LTS o superior (recomendado)
- Alternativas: Debian, CentOS, Rocky Linux
- Windows WSL2 (para desarrollo local)
📦 Paso 1: Preparación del Entorno
1.1 Crear Directorio de Proyecto
mkdir -p ~/n8n-docker && cd ~/n8n-docker
1.2 Crear Archivo .env con Variables Críticas
⚠️ CRÍTICO: Genera N8N_ENCRYPTION_KEY antes del primer inicio. Perderla = perder todas las credenciales.
# Generar key de encriptación (ejecutar una vez)
export N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
echo "N8N_ENCRYPTION_KEY=$N8N_ENCRYPTION_KEY" >> .env
# Crear archivo .env completo
cat > .env << 'EOF'
# === BASE DE DATOS POSTGRES ===
POSTGRES_USER=n8n
POSTGRES_PASSWORD=change_this_password_aleatorio_seguro
POSTGRES_DB=n8n_production
# === CONFIGURACIÓN N8N ===
N8N_HOST=n8n.tudominio.com # Tu dominio público (sin http://)
N8N_PORT=5678
N8N_PROTOCOL=https
# === WEBHOOKS Y PROXY ===
N8N_WEBHOOK_URL=https://n8n.tudominio.com/ # Reemplaza WEBHOOK_URL (v2.35+)
N8N_PROXY_HOPS=1
# === AUTENTICACIÓN BÁSICA ===
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=change_this_password_seguro
# === ZONA HORARIA ===
GENERIC_TIMEZONE=Africa/Tunis # O Europe/Madrid, etc.
TZ=Africa/Tunis
EOF
🐳 Paso 2: Crear docker-compose.yml
Configuración de Producción Completa
version: "3.8"
services:
# === POSTGRESQL (Base de Datos Persistente) ===
postgres:
image: postgres:16
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
# === N8N (Aplicación Principal) ===
n8n:
image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
restart: always
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_HOST=${N8N_HOST}
- N8N_PORT=${N8N_PORT}
- N8N_PROTOCOL=${N8N_PROTOCOL}
- WEBHOOK_URL=${N8N_WEBHOOK_URL}
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${TZ}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_BASIC_AUTH_ACTIVE=${N8N_BASIC_AUTH_ACTIVE}
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files # Opcional: para archivos locales
depends_on:
postgres:
condition: service_healthy
# === N8N RUNNER (Contenedor Separado para Ejecución de Código) ===
n8n-runner:
image: n8nio/runners:${N8N_VERSION}
restart: always
environment:
- N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN:-${N8N_ENCRYPTION_KEY}}
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
depends_on:
- n8n
volumes:
postgres_data:
n8n_data:
🚀 Paso 3: Iniciar el Stack
Descargar Imágenes y Arrancar
# Descargar imágenes y arrancar en segundo plano
docker compose up -d
# Verificar estado de los contenedores
docker compose ps
# Esperar a que PostgreSQL esté listo (primer inicio)
sleep 30
# Ver logs del servicio n8n
docker compose logs -f n8n
Acceso Inicial
Visita en tu navegador:
http://tu-servidor-ip:5678https://n8n.tudominio.com
Primera vez: Se mostrará la pantalla de registro del usuario propietario. Crea una cuenta con tus credenciales.
🔒 Paso 4: Configurar SSL/HTTPS (Caddy - Recomendado)
Instalar Caddy
# Instalar Caddy en Ubuntu/Debian
curl -s https://caddyserver.com/download | \
gunzip | \
tar -xvzf caddy_*.deb_amd64.deb \
&& sudo dpkg -i caddy*.deb \
&& sudo rm caddy*.deb*
# Configurar Caddyfile
sudo nano /etc/caddy/Caddyfile
Crear Caddyfile para n8n
n8n.tudominio.com {
reverse_proxy localhost:5678
# Headers de seguridad
header respond Strict-Transport-Security "max-age=31536000; includeSubDomains"
header respond X-Frame-Options "SAMEORIGIN"
header respond X-Content-Type-Options "nosniff"
}
Alternativa: Nginx con Let's Encrypt
# Instalar Nginx y Certbot
sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx
# Obtener certificado SSL
sudo certbot --standalone -d n8n.tudominio.com
📊 Paso 5: Verificación y Pruebas
Comprobar Estado del Sistema
# Verificar todos los contenedores están saludables
docker compose ps
# Deberías ver:
# postgres - healthy
# n8n - running
# n8n-runner - running
Probar Webhooks
Crear un workflow simple con webhook. La URL debe mostrar tu dominio, NO localhost.
Verificar Autenticación
Intentar acceder sin credenciales. Deberías ver pantalla de login con admin/change_this_password_seguro.
💾 Paso 6: Copias de Seguridad y Mantenimiento
Backup de PostgreSQL
#!/bin/bash
BACKUP_DIR="/backup/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
docker compose exec postgres pg_dump -U n8n n8n_production > \
"${BACKUP_DIR}/n8n_backup_${DATE}.sql"
# Comprimir backup
tar -czf "${BACKUP_DIR}/n8n_backup_${DATE}.tar.gz" \
"${BACKUP_DIR}/n8n_backup_${DATE}.sql"
Backup de Datos de n8n (Workflows, Credenciales)
# Copiar datos completos del volumen
docker cp n8n:/home/node/.n8n /backup/n8n_data/$(date +%Y%m%d)/
🔄 Paso 7: Actualización Segura de n8n
Proceso de Actualización (Sin Perder Datos)
# 1. Detener contenedores
docker compose down
# 2. Descargar nueva imagen
docker compose pull
# 3. Reiniciar con nueva versión
docker compose up -d
# 4. Verificar logs para confirmar inicio limpio
docker compose logs -f n8n
Rollback si hay Problemas
# Si la actualización falla, volver a versión anterior
cat > docker-compose.yml << 'YAML_EOF'
version: "3.8"
services:
n8n:
image: docker.n8n.io/n8nio/n8n:v1.15.0 # Versión anterior
# ...
YAML_EOF
docker compose up -d
🐛 Paso 8: Solución de Problemas Comunes
Error 1: "Connection to database failed"
Causa: n8n intentó conectarse antes de que PostgreSQL estuviera listo.
Solución: Verificar healthcheck en docker-compose.yml con depends_on: condition: service_healthy
Error 2: "Credentials could not be decrypted"
Causa: N8N_ENCRYPTION_KEY no está configurada o se perdió.
Solución: Generar nueva key con openssl rand -hex 32 y actualizar .env.
Error 3: Webhook URL muestra localhost
Causa: Variables N8N_WEBHOOK_URL o N8N_PROXY_HOPS no configuradas correctamente.
Solución: Verificar que N8N_WEBHOOK_URL=https://n8n.tudominio.com/ y N8N_PROXY_HOPS=1
📚 FAQ - Preguntas Frecuentes
¿Puedo usar SQLite en lugar de PostgreSQL?
Respuesta: Sí, para testing básico. Pero para producción se recomienda PostgreSQL por mejor manejo de concurrencia y backups más robustos.
¿Necesito el runner container?
Respuesta: Sí, desde n8n v1.15+ es parte del setup oficial. Ejecuta código en contenedor separado por seguridad y escalabilidad.
¿Qué pasa si pierdo N8N_ENCRYPTION_KEY?
Respuesta: Todas las credenciales guardadas se vuelven ilegibles permanentemente. Genera una nueva key antes del primer inicio y respaldala fuera del contenedor.
¿Puedo escalar horizontalmente?
Respuesta: Sí, con queue mode necesitas PostgreSQL, Redis adicional, múltiples workers n8n-runner y S3-compatible storage para binarios.
🔗 Enlaces Internos y Recursos
⚠️ Notas Importantes
- Nunca uses las contraseñas de ejemplo en producción. Genera credenciales seguras con
openssl rand -hex 32. - Siempre configura N8N_ENCRYPTION_KEY antes del primer inicio. Perderla = perder todas las credenciales.
- Usa HTTPS siempre. Los webhooks y OAuth requieren conexión segura.
- Mantén backups regulares de PostgreSQL y datos de workflows.
- Actualiza periódicamente siguiendo el proceso seguro descrito en esta guía.