n8n self-hosted: cuándo tiene sentido y cuándo estás creando un problema
Análisis honesto sobre n8n self-hosted: ventajas, riesgos, seguridad, mantenimiento y casos donde no lo usaría.

Llevo tiempo usando n8n self-hosted para automatizaciones internas y proyectos personales. Es una herramienta que me ha ahorrado horas de trabajo, pero también me ha dado algún susto que podría haberse evitado si hubiera sido más disciplinado desde el principio. Lo que voy a contar aquí no es un tutorial de instalación ni un panfleto de marketing. Es un análisis honesto de cuándo montar n8n en tu propia infra merece la pena y cuándo te estás comprando un problema que no necesitas.
La versión cloud de n8n existe y funciona. Si la opción self-hosted sigue siendo popular es por tres razones: control total sobre los datos, flexibilidad para personalizaciones, y que no tiene coste de licencia por ejecución. Pero cada una de esas ventajas viene con una responsabilidad que mucha gente subestima.
Cuándo sí tiene sentido ir self-hosted
No voy a decir “siempre” porque sería mentira. Hay escenarios concretos donde montar n8n en tu propio servidor tiene todo el sentido.
Automatizaciones internas de equipo
Si tu equipo necesita conectar herramientas internas ---base de datos, Slack, repositorios, dashboards--- y no quieres pagar por cada ejecución, self-hosted es ideal. El tráfico es predecible, los usuarios son conocidos, y el riesgo de escalado descontrolado es bajo.
Prototipos y validaciones rápidas
Cuando necesitas probar una integración nueva o montar un flujo rápido para un cliente, tener n8n en tu máquina local o en un servidor de desarrollo es mucho más ágil que configurar una suscripción cloud para un experimento que quizá dure una semana.
Equipos pequeños con algo de conocimiento ops
Si hay alguien en el equipo que sabe manejar Docker, mantener un servidor actualizado y configurar backups, n8n self-hosted no requiere un equipo de infraestructura dedicado. Un VPS barato con Docker Compose es suficiente para muchos casos.
Datos que no pueden salir de tu red
En sectores regulados o proyectos donde los datos son sensibles, tener el motor de automatización dentro de tu infraestructura puede ser un requisito, no una preferencia. Self-hosted te da esa garantía de que nada sale de tu red.
Cuándo NO tiene sentido
Aquí es donde la conversación se pone incómoda, porque muchas veces la decisión de ir self-hosted se toma por inercia, por ahorro percibido o por una falsa sensación de control.
Cuando necesitas alta disponibilidad y no tienes infra
Si tu workflow de n8n es crítico ---por ejemplo, procesa pagos, envía notificaciones a clientes o alimenta un sistema en producción--- y tu setup es un Docker Compose en un VPS sin redundancia, estás jugando con fuego. Si el servidor cae, los workflows se pierden. Si el disco se llena, n8n deja de funcionar sin avisar.
Si tu automatización es crítica para el negocio y no tienes capacidad para garantizar disponibilidad, la versión cloud probablemente te salga más barata que la primera caída.
Cuando manejas datos sensibles sin infra adecuada
Self-hosted te da control, pero el control sin disciplina es peor que delegarlo a un proveedor competente. Si vas a procesar datos personales, credenciales de clientes o información financiera en un n8n montado en un VPS sin HTTPS, sin firewall bien configurado, y con credenciales de admin por defecto, el riesgo es real.
Cuando nadie en el equipo quiere mantenerlo
n8n hay que actualizarlo. El servidor hay que parchearlo. Los backups hay que hacerlos. Si montas n8n self-hosted y nadie asume la responsabilidad de mantenerlo, en seis meses tendrás una versión desactualizada con vulnerabilidades conocidas y sin backups. Lo he visto pasar.
Cuando el coste real supera el de cloud
Saca la cuenta honesta. Un VPS, el tiempo de un dev manteniendo el setup, el riesgo de downtime, el tiempo de debugging cuando algo falla. Si el equipo es de tres personas y la alternativa cloud cuesta 20 euros al mes, el self-hosted puede salir más caro en horas de trabajo aunque el servidor sea barato.
Docker setup: un punto de partida realista
Si después de evaluar los riesgos decides que self-hosted es tu camino, este es un docker-compose.yml que uso como base. No es el mínimo ejemplo de la documentación; tiene las configuraciones que considero necesarias para algo que va más allá de un experimento.
# docker-compose.yml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
# Configuración básica
- N8N_HOST=n8n.tudominio.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.tudominio.com/
# Base de datos externa (NO usar SQLite en producción)
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Seguridad
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
# Zona horaria
- GENERIC_TIMEZONE=Europe/Madrid
- TZ=Europe/Madrid
# Encryption key para credenciales (IMPORTANTE: no perder esta clave)
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
networks:
- n8n-network
postgres:
image: postgres:16-alpine
container_name: n8n-postgres
restart: unless-stopped
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- n8n-network
volumes:
n8n_data:
postgres_data:
networks:
n8n-network:
driver: bridgeY el .env correspondiente:
# .env
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=una_password_segura_de_verdad
N8N_USER=admin
N8N_PASSWORD=otra_password_segura
N8N_ENCRYPTION_KEY=genera-una-clave-larga-aleatoria-aquiPor qué PostgreSQL y no SQLite
SQLite es el default de n8n y funciona para probar. Pero en producción tiene problemas reales:
- No soporta bien escrituras concurrentes. Si tienes varios workflows ejecutándose a la vez, puedes tener bloqueos.
- Los backups son más frágiles. Copiar un archivo SQLite mientras n8n está escribiendo puede generar un backup corrupto.
- No escala. Si tus workflows generan volumen de ejecuciones, SQLite se convierte en un cuello de botella.
PostgreSQL resuelve todo esto y n8n lo soporta nativamente.
Seguridad: lo que no puedes ignorar
La seguridad de un n8n self-hosted no es trivial, y es probablemente el aspecto que más gente subestima. n8n ejecuta código, se conecta a servicios externos, y almacena credenciales de APIs, bases de datos y servicios de terceros. Si alguien obtiene acceso a tu instancia, tiene acceso a todo eso.
HTTPS obligatorio
No expongas n8n por HTTP. Nunca. Las credenciales viajan en texto plano, los webhooks son accesibles desde internet, y cualquier persona en la misma red puede interceptar el tráfico.
La forma más sencilla de añadir HTTPS es poner un reverse proxy delante. Un ejemplo con Caddy, que gestiona certificados automáticamente:
# Caddyfile
n8n.tudominio.com {
reverse_proxy n8n:5678
}O con nginx:
server {
listen 443 ssl;
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;
# WebSocket support (necesario para el editor de n8n)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Red interna siempre que sea posible
Si n8n solo lo usa tu equipo, no necesita estar expuesto a internet. Ponlo en una red interna y accede por VPN. Esto elimina de golpe la mayoría de vectores de ataque.
Autenticación
n8n tiene autenticación básica integrada, pero no es sofisticada. Si necesitas SSO, MFA o control de acceso por roles, la versión self-hosted comunitaria se queda corta. La versión enterprise sí lo ofrece, pero tiene coste.
Lo mínimo que deberías configurar:
- Basic auth activo con passwords fuertes.
- Cambiar las credenciales por defecto (parece obvio, pero no lo es).
- Si usas webhooks públicos, limitar por IP o añadir tokens de autenticación en los propios workflows.
Backups: lo que no puedes permitirte perder
He visto a gente perder workflows enteros porque el servidor se cayó y no había backup. La buena noticia es que hacer backup de n8n es sencillo si usas PostgreSQL.
Qué necesitas respaldar
- La base de datos PostgreSQL. Contiene los workflows, las ejecuciones y las credenciales cifradas.
- El fichero de encryption key. Sin esta clave, las credenciales almacenadas son irrecuperables.
- El volumen de n8n (
.n8n). Contiene configuración y archivos que suben los workflows.
Script de backup automatizado
#!/bin/bash
# backup_n8n.sh - Ejecutar con cron diariamente
BACKUP_DIR="/backups/n8n"
DATE=$(date +%Y-%m-%d_%H%M)
RETENTION_DAYS=30
mkdir -p "$BACKUP_DIR"
# 1. Backup de PostgreSQL
docker exec n8n-postgres pg_dump \
-U n8n_user \
-d n8n \
--format=custom \
> "$BACKUP_DIR/n8n_db_${DATE}.dump"
echo "[BACKUP] Base de datos exportada: n8n_db_${DATE}.dump"
# 2. Backup del volumen de n8n
docker run --rm \
-v n8n_data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/n8n_data_${DATE}.tar.gz" -C /source .
echo "[BACKUP] Volumen n8n exportado: n8n_data_${DATE}.tar.gz"
# 3. Copiar encryption key (si está en .env)
cp /path/to/your/.env "$BACKUP_DIR/env_${DATE}.bak"
# 4. Limpiar backups antiguos
find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete
echo "[BACKUP] Completado. Backups antiguos (>$RETENTION_DAYS días) eliminados."Configúralo con cron:
# Ejecutar backup diario a las 3:00 AM
0 3 * * * /path/to/backup_n8n.sh >> /var/log/n8n_backup.log 2>&1La encryption key de n8n es lo más importante que debes respaldar. Si la pierdes, todas las credenciales almacenadas en n8n se vuelven irrecuperables. Guárdala en un lugar seguro fuera del servidor.
Gestión de credenciales: cómo las guarda n8n y qué riesgos hay
n8n cifra las credenciales antes de guardarlas en la base de datos. Usa AES-256-CBC con la encryption key que defines en la configuración. Esto significa que incluso si alguien accede a tu base de datos, las credenciales no son legibles directamente.
Pero hay matices importantes:
La encryption key es un single point of failure
Si defines la encryption key como variable de entorno y el servidor se pierde sin backup de esa variable, las credenciales cifradas en la base de datos son inútiles. He visto equipos que tenían backup de la DB pero no de la encryption key. Resultado: workflows recuperados, pero todas las credenciales rotas.
Credenciales en workflows compartidos
Cuando exportas un workflow de n8n, las credenciales NO se exportan. Esto es bueno por seguridad, pero significa que al importar un workflow en otra instancia tienes que reconfigurar cada credencial manualmente. Si tienes 15 workflows con 40 credenciales, la migración no es trivial.
Rotación de credenciales
n8n no tiene un sistema de rotación de credenciales integrado. Si un token de API caduca, tienes que ir al editor y cambiarlo manualmente. Para equipos pequeños esto es manejable. Para setups con docenas de integraciones, empieza a ser un problema operativo.
Buenas prácticas
- Documenta qué credenciales usa cada workflow.
- Guarda la encryption key en un gestor de secretos (Vault, AWS Secrets Manager, o al menos un fichero cifrado fuera del servidor).
- Revisa periódicamente qué credenciales están activas y cuáles son obsoletas.
- Nunca guardes tokens o passwords directamente en los nodos de n8n si puedes usar variables de entorno o un servicio de secretos externo.
Actualizaciones: el mantenimiento que nadie quiere hacer
n8n publica releases con frecuencia. Algunas incluyen correcciones de seguridad. Si tu instancia self-hosted se queda sin actualizar, acumulas vulnerabilidades conocidas.
Proceso de actualización con Docker
#!/bin/bash
# update_n8n.sh
echo "[UPDATE] Haciendo backup antes de actualizar..."
/path/to/backup_n8n.sh
echo "[UPDATE] Parando n8n..."
docker compose down
echo "[UPDATE] Descargando nueva versión..."
docker compose pull
echo "[UPDATE] Arrancando n8n..."
docker compose up -d
echo "[UPDATE] Comprobando estado..."
sleep 10
docker compose ps
echo "[UPDATE] Completado."Mi recomendación: no fijes la imagen a latest si no quieres sorpresas. Usa un tag concreto y actualiza de forma controlada:
image: n8nio/n8n:1.42.1 # en vez de n8nio/n8n:latestAsí puedes probar la nueva versión en un entorno de desarrollo antes de actualizar producción.
Monitorización básica
Un n8n self-hosted sin monitorización es un agujero negro. No sabes si está funcionando, no sabes si los workflows fallan, no sabes si el disco se está llenando.
Lo mínimo que yo pongo:
#!/bin/bash
# health_check_n8n.sh
# Verificar que n8n responde
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5678/healthz)
if [ "$HTTP_CODE" != "200" ]; then
echo "[ALERT] n8n no responde. HTTP code: $HTTP_CODE"
# Aquí podrías enviar alerta a Slack, email, etc.
curl -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d '{"text": "n8n self-hosted no responde. Revisar urgente."}'
fi
# Verificar espacio en disco
DISK_USAGE=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 85 ]; then
echo "[ALERT] Disco al ${DISK_USAGE}%"
fiMi criterio resumido
| Factor | Self-hosted | Cloud |
|---|---|---|
| Control total de datos | Si | No |
| Sin coste por ejecución | Si | No |
| Automatizaciones internas | Buena opción | Puede ser overkill |
| Alta disponibilidad necesaria | Solo si tienes infra | Si |
| Equipo sin experiencia ops | Riesgo alto | Mejor opción |
| Datos sensibles con infra adecuada | Si | Depende del proveedor |
| Presupuesto muy limitado | Si | No |
| Pocos workflows, pocas ejecuciones | Overkill | Mejor opción |
Lo que me hubiera gustado hacer desde el primer día
Si volviera a montar un n8n self-hosted desde cero, haría tres cosas antes de crear el primer workflow:
- Configurar PostgreSQL en vez de SQLite. La migración posterior es posible pero molesta.
- Configurar backups automáticos. No “mañana lo hago”. Antes del primer workflow.
- Guardar la encryption key en un lugar seguro. No en el mismo servidor. No en un post-it. En un gestor de secretos o en un fichero cifrado en otro sitio.
El self-hosted de n8n es una buena opción cuando sabes lo que estás haciendo y aceptas la responsabilidad que viene con el control. Si lo que quieres es montar workflows rápido sin pensar en servidores, backups o seguridad, la versión cloud existe precisamente para eso. No hay vergüenza en usarla.


