Instalar n8n con Docker Self-Hosted: Guía Completa para tu Servidor
Instala n8n self-hosted con Docker en tu servidor paso a paso. Docker Compose, PostgreSQL, HTTPS con Traefik y backups. Guía práctica 2026.
Instalar n8n con Docker Self-Hosted: Guía Completa para tu Servidor
Quieres instalar n8n con Docker en tu propio servidor y no depender de la nube de nadie. Perfecto. Eso es exactamente lo que vamos a hacer aquí: montar una instancia de n8n self-hosted que funcione en producción de verdad, no un contenedor que se cae al primer reinicio.
La documentación oficial de n8n te da los comandos básicos y te desea suerte. En esta guía vamos más allá: Docker Compose con PostgreSQL como base de datos, HTTPS con Traefik como reverse proxy, persistencia de datos correcta y una estrategia de backups para que no pierdas tus workflows el día que algo falle.
Si ya sabes qué es n8n y quieres ir al grano, salta directamente a la sección de requisitos previos. Si necesitas contexto, sigue leyendo.
Por qué self-hosted y no n8n Cloud
n8n Cloud funciona bien. Pagas, accedes y te olvidas del servidor. Pero tiene tres limitaciones que para muchos son un problema:
Precio. El plan starter de n8n Cloud ronda los 20 €/mes con ejecuciones limitadas. Un VPS de 4 GB de RAM donde correr n8n self-hosted cuesta entre 5 y 10 €/mes con ejecuciones ilimitadas. Si tus workflows procesan miles de ejecuciones diarias, la diferencia económica es brutal.
Control de datos. Cuando automatizas facturación, CRM, bases de datos o procesos internos de una empresa, tus datos pasan por los servidores de n8n. Con self-hosted, todo se queda en tu máquina. Para cumplir con RGPD o si trabajas con información sensible de clientes, esto no es un detalle menor.
Flexibilidad técnica. En la versión self-hosted puedes instalar nodos comunitarios, conectar con servicios internos de tu red, ajustar recursos del servidor según necesites y configurar todo a tu medida. En Cloud estás limitado a lo que n8n decide ofrecerte.
¿Cuándo tiene sentido n8n Cloud? Si no quieres tocar un servidor, si haces pocas automatizaciones y si el coste no te preocupa. Para todos los demás casos, self-hosted es la opción inteligente.
Por qué Docker y no instalación nativa
Podrías instalar n8n directamente con npm (npm install n8n -g). Funciona, pero es una mala idea para producción por tres razones:
- Dependencias: n8n necesita Node.js en una versión específica. Actualizar Node.js en tu servidor puede romper n8n, y viceversa. Docker aísla todo eso.
- Reproducibilidad: con Docker, tu entorno es idéntico en cualquier máquina. Lo que funciona en tu servidor de desarrollo funciona igual en producción.
- Actualizaciones limpias: actualizar n8n es cambiar la etiqueta de la imagen Docker. Sin conflictos de dependencias, sin paquetes rotos.
Docker no es opcional aquí. Es la forma correcta de hacerlo.
Requisitos previos: lo que necesitas antes de empezar
Antes de tocar un solo comando, asegúrate de que tienes esto resuelto:
Servidor (VPS o máquina física):
- Sistema operativo: Ubuntu 22.04/24.04 LTS, Debian 12 o cualquier Linux moderno
- RAM mínima: 2 GB (recomendado 4 GB si vas a usar nodos de IA)
- Almacenamiento: 20 GB mínimo
- Acceso SSH con usuario no root que tenga permisos sudo
Software instalado:
- Docker Engine (versión 24+)
- Docker Compose v2 (incluido en Docker Engine moderno)
Red y dominio (para HTTPS):
- Un dominio o subdominio apuntando a la IP de tu servidor (por ejemplo,
n8n.tudominio.com) - Puertos 80 y 443 abiertos en el firewall
Si aún no tienes Docker instalado, aquí va el proceso para Ubuntu/Debian:
# Actualizar el sistema
sudo apt update && sudo apt upgrade -y
# Instalar dependencias
sudo apt install -y ca-certificates curl gnupg
# Añadir clave GPG oficial de Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Añadir repositorio de Docker
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Instalar Docker Engine y Docker Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Añadir tu usuario al grupo docker (para no usar sudo cada vez)
sudo usermod -aG docker $USER
newgrp docker
# Verificar la instalación
docker --version
docker compose version
Si usas Debian en lugar de Ubuntu, cambia ubuntu por debian en la URL del repositorio. Para otros sistemas, consulta la documentación oficial de Docker.
Opción rápida: n8n con Docker en un solo comando
Si solo quieres probar n8n en local para ver cómo funciona, esto basta:
docker volume create n8n_data
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="Europe/Madrid" \
-e TZ="Europe/Madrid" \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Abre http://localhost:5678 y tienes n8n corriendo. Pero esto no es producción: usa SQLite, no tiene HTTPS, no sobrevive a un reinicio del servidor y no tiene backup de nada.
Para un despliegue real, necesitas Docker Compose. Que es exactamente lo que viene ahora.
Instalación de producción con Docker Compose y PostgreSQL
Esta es la configuración que yo uso y recomiendo. Incluye:
- n8n con la última versión estable
- PostgreSQL como base de datos (mucho más fiable que SQLite para producción)
- Traefik como reverse proxy con HTTPS automático vía Let’s Encrypt
- Volúmenes persistentes para que nada se pierda al reiniciar
Paso 1: Crear la estructura de directorios
mkdir -p ~/n8n-server/{traefik,postgres-data}
cd ~/n8n-server
touch traefik/acme.json
chmod 600 traefik/acme.json
El archivo acme.json es donde Traefik guarda los certificados SSL. El permiso 600 es obligatorio o Traefik se niega a arrancar.
Paso 2: Crear el archivo .env
Crea un archivo .env en ~/n8n-server/ con tus datos:
# Dominio donde se servirá n8n
N8N_HOST=n8n.tudominio.com
N8N_PROTOCOL=https
N8N_PORT=443
# Zona horaria
GENERIC_TIMEZONE=Europe/Madrid
TZ=Europe/Madrid
# Seguridad - genera una clave aleatoria con: openssl rand -hex 32
N8N_ENCRYPTION_KEY=aqui-tu-clave-de-encriptacion-generada
# PostgreSQL
POSTGRES_USER=n8n
POSTGRES_PASSWORD=una-contraseña-segura-aqui
POSTGRES_DB=n8n
POSTGRES_NON_ROOT_USER=n8n
POSTGRES_NON_ROOT_PASSWORD=una-contraseña-segura-aqui
# Email para Let's Encrypt
[email protected]
Genera la clave de encriptación con:
openssl rand -hex 32
Esta clave es crítica: n8n la usa para cifrar las credenciales de tus integraciones. Si la pierdes, pierdes acceso a todas las credenciales almacenadas. Guárdala en un lugar seguro fuera del servidor.
Paso 3: Crear el docker-compose.yml
services:
traefik:
image: traefik:v3.1
restart: unless-stopped
command:
- "--api=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
- "--certificatesresolvers.mytlschallenge.acme.email=${LETSENCRYPT_EMAIL}"
- "--certificatesresolvers.mytlschallenge.acme.storage=/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- ./traefik/acme.json:/acme.json
- /var/run/docker.sock:/var/run/docker.sock:ro
postgres:
image: postgres:16-alpine
restart: unless-stopped
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: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PORT=${N8N_PORT}
- N8N_PROTOCOL=${N8N_PROTOCOL}
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${TZ}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- N8N_RUNNERS_ENABLED=true
- 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}
volumes:
- n8n_data:/home/node/.n8n
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`${N8N_HOST}`)"
- "traefik.http.routers.n8n.tls=true"
- "traefik.http.routers.n8n.tls.certresolver=mytlschallenge"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
volumes:
n8n_data:
Paso 4: Arrancar todo
cd ~/n8n-server
docker compose up -d
Espera unos 30 segundos. Comprueba que todo está corriendo:
docker compose ps
Deberías ver tres contenedores en estado running o Up. Si PostgreSQL muestra healthy, perfecto. Ahora accede a https://n8n.tudominio.com desde tu navegador.
La primera vez, n8n te pedirá crear una cuenta de administrador. Usa una contraseña fuerte: este panel tendrá acceso a todas tus automatizaciones y credenciales.
Configurar n8n después de la instalación
Una vez dentro del panel, hay ajustes que deberías revisar antes de crear tu primer workflow.
Variables de entorno importantes
Estas variables se añaden en el bloque environment de n8n dentro de tu docker-compose.yml:
# Limitar ejecuciones almacenadas (evita que PostgreSQL crezca sin control)
- EXECUTIONS_DATA_MAX_AGE=168 # Borrar ejecuciones de más de 7 días
- EXECUTIONS_DATA_PRUNE=true # Activar poda automática
# Logging
- N8N_LOG_LEVEL=info # Opciones: silent, error, warn, info, debug
# Deshabilitar telemetría (opcional, por privacidad)
- N8N_DIAGNOSTICS_ENABLED=false
# Webhook URL (ya definida, pero fundamental para que los webhooks funcionen)
- WEBHOOK_URL=https://n8n.tudominio.com/
Después de modificar variables de entorno, reinicia con:
docker compose down && docker compose up -d
Webhooks y firewall
Si tus workflows usan webhooks (que los usarán), asegúrate de que tu firewall permite tráfico HTTPS entrante. Con UFW en Ubuntu:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Los webhooks de n8n se exponen bajo la URL https://n8n.tudominio.com/webhook/ o https://n8n.tudominio.com/webhook-test/ para pruebas. Traefik se encarga de enrutar el tráfico correctamente.
Actualizar n8n a la última versión
Una de las ventajas de Docker: actualizar es trivial.
cd ~/n8n-server
# Descargar la última imagen
docker compose pull
# Reiniciar con la nueva versión
docker compose up -d
Eso es todo. Docker descarga la imagen nueva, para el contenedor antiguo y arranca el nuevo con los mismos datos. Tus workflows, credenciales y configuración se mantienen porque están en los volúmenes persistentes.
Consejo: antes de actualizar, haz un backup de la base de datos. Las migraciones automáticas de n8n funcionan bien el 99 % de las veces, pero ese 1 % te puede arruinar el día.
Backups: la parte que todo el mundo olvida
No tener backups no es una opción. Estas son las dos cosas que necesitas respaldar:
Backup de PostgreSQL
# Backup manual
docker compose exec postgres pg_dump -U n8n n8n > backup_n8n_$(date +%Y%m%d_%H%M%S).sql
# Restaurar
cat backup_archivo.sql | docker compose exec -T postgres psql -U n8n n8n
Backup del volumen de datos de n8n
# El volumen contiene claves de encriptación y configuración
docker run --rm \
-v n8n-server_n8n_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/n8n_data_$(date +%Y%m%d).tar.gz /data
Script de backup automático
Crea un archivo backup.sh en ~/n8n-server/:
#!/bin/bash
BACKUP_DIR=~/n8n-backups
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# Backup PostgreSQL
docker compose -f ~/n8n-server/docker-compose.yml exec -T postgres \
pg_dump -U n8n n8n > "$BACKUP_DIR/n8n_db_$DATE.sql"
# Backup volumen n8n
docker run --rm \
-v n8n-server_n8n_data:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf "/backup/n8n_data_$DATE.tar.gz" /data
# Eliminar backups de más de 30 días
find $BACKUP_DIR -type f -mtime +30 -delete
echo "Backup completado: $DATE"
Hazlo ejecutable y ponlo en cron:
chmod +x ~/n8n-server/backup.sh
# Backup diario a las 3:00 AM
crontab -e
# Añadir esta línea:
0 3 * * * /home/tu-usuario/n8n-server/backup.sh >> /home/tu-usuario/n8n-backups/backup.log 2>&1
Solución de problemas comunes
n8n no arranca
Revisa los logs:
docker compose logs n8n
Los errores más frecuentes:
- “EACCES: permission denied”: los permisos del volumen de datos no son correctos. Solución:
docker volume rm n8n-server_n8n_datay volver a arrancar (perderás datos si no tienes backup). - “Connection refused” a PostgreSQL: el contenedor de Postgres aún no está listo. Con el
healthcheckque hemos definido,depends_onespera a que Postgres esté sano antes de arrancar n8n. - Puerto 5678 ya en uso: otro servicio está usando ese puerto. Cambia el mapeo en docker-compose o para el otro servicio.
Certificado SSL no funciona
- Verifica que tu dominio apunta a la IP del servidor:
dig n8n.tudominio.com - Comprueba que los puertos 80 y 443 están abiertos:
sudo ufw status - Revisa los logs de Traefik:
docker compose logs traefik - Asegúrate de que
acme.jsontiene permisos 600
Los webhooks no reciben datos
- Comprueba que
WEBHOOK_URLen tu.envcoincide exactamente con tu dominio, incluyendohttps://y la barra final. - Los webhooks de prueba (
/webhook-test/) solo funcionan mientras el workflow está abierto en el editor. - Algunos firewalls corporativos bloquean callbacks. Prueba desde fuera de tu red.
Alto uso de disco
PostgreSQL almacena todas las ejecuciones por defecto. Si llevas semanas corriendo workflows, la base de datos puede crecer mucho. Activa la poda automática con las variables EXECUTIONS_DATA_PRUNE=true y EXECUTIONS_DATA_MAX_AGE=168 (7 días).
Seguridad: lo que no puedes ignorar
Tener n8n expuesto a Internet es tener un panel de administración con acceso a todas tus APIs, bases de datos y servicios conectados. Protégelo:
Contraseña robusta. Usa un gestor de contraseñas. Si alguien accede a tu n8n, tiene acceso a todo lo que tus workflows pueden hacer.
Mantén n8n actualizado. Los parches de seguridad se publican con frecuencia. Revisa el changelog de n8n al menos una vez al mes.
Restringe el acceso si puedes. Si solo tú usas n8n, limítalo a tu IP o ponlo detrás de una VPN como Tailscale o WireGuard. Traefik permite añadir middleware de IP whitelist:
# Añadir al servicio n8n en docker-compose.yml
labels:
- "traefik.http.middlewares.n8n-ipwhitelist.ipwhitelist.sourcerange=TU.IP.AQUI/32"
- "traefik.http.routers.n8n.middlewares=n8n-ipwhitelist"
SSH hardening. Si tu servidor está en Internet, desactiva el acceso SSH con contraseña y usa solo claves. Cambia el puerto por defecto. Instala fail2ban.
No expongas PostgreSQL. En nuestra configuración, PostgreSQL solo es accesible desde la red interna de Docker. Mantenlo así.
Arquitectura alternativa: n8n detrás de Nginx
Si ya tienes Nginx en tu servidor y no quieres añadir Traefik, puedes usar Nginx como reverse proxy. El docker-compose.yml se simplifica:
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
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: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "5678:5678"
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${TZ}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- N8N_RUNNERS_ENABLED=true
- 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}
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
Y la configuración de Nginx:
server {
listen 80;
server_name n8n.tudominio.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.tudominio.com;
ssl_certificate /etc/letsencrypt/live/n8n.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.tudominio.com/privkey.pem;
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
}
}
Los headers de Upgrade y Connection son necesarios para que los WebSockets de n8n funcionen correctamente. Sin ellos, el editor puede tener problemas de conexión.
Rendimiento: qué esperar de tu servidor
Con un VPS de 4 GB de RAM, n8n con PostgreSQL puede manejar sin problemas:
- Decenas de workflows activos simultáneamente
- Miles de ejecuciones diarias
- Nodos de IA con modelos externos (OpenAI, Anthropic, Ollama)
- Webhooks con tiempos de respuesta inferiores a 200 ms
Si necesitas escalar más allá de eso, n8n soporta modo multi-instancia con una cola de trabajos, pero eso es tema para otro artículo. Para la mayoría de usuarios y PYMEs, un solo servidor es más que suficiente.
Monitorización básica: revisa periódicamente el uso de recursos con docker stats y el tamaño de la base de datos. Si PostgreSQL supera los 2 GB, revisa la retención de ejecuciones.
Resumen: tu checklist de instalación
Para que no se te escape nada, aquí va la lista ordenada:
- Servidor con Ubuntu/Debian, mínimo 2 GB RAM y Docker instalado
- Dominio apuntando a la IP del servidor
- Directorio
~/n8n-servercon.env,docker-compose.ymly carpetatraefik/ - Archivo
acme.jsoncon permisos 600 - Clave de encriptación generada con
openssl rand -hex 32y guardada en lugar seguro docker compose up -dy verificar condocker compose ps- Crear cuenta de administrador en
https://n8n.tudominio.com - Configurar poda de ejecuciones y variables de entorno adicionales
- Script de backup en cron
- Restringir acceso por IP o VPN si es posible
Siguiente paso: automatiza algo
Tener n8n instalado no sirve de nada si no automatizas procesos con él. Si acabas de empezar, echa un vistazo a nuestra guía de primeros pasos con n8n donde montamos tres workflows prácticos desde cero.
Si lo tuyo es la automatización industrial y quieres conectar n8n con PLCs, bases de datos de producción o sistemas SCADA, en automatizatodo.com publicamos guías especializadas todas las semanas.
¿Necesitas ayuda con tu instalación o quieres un despliegue profesional para tu empresa? Contáctanos y lo montamos por ti.
Sigue leyendo
Cómo Usar n8n como CRM para Automatizar el Seguimiento de Clientes en tu PYME
Aprende a usar n8n como CRM automatizado para tu PYME. Configura seguimiento de clientes, recordatorios y pipelines de ventas sin pagar licencias caras.
Leer artículoCómo Automatizar tu Backend con n8n, Supabase y PostgreSQL: Guía Práctica
Aprende a automatizar tu backend con n8n y Supabase PostgreSQL. 4 workflows prácticos para gestionar datos, webhooks y lógica sin escribir servidor.
Leer artículo