n8n es una plataforma de automatización de flujos de trabajo de código abierto (fair-code) que te permite conectar aplicaciones, APIs y servicios sin escribir apenas código. A diferencia de Zapier o Make, donde pagas por cada tarea ejecutada, n8n self-hosted corre en tu propia infraestructura con un coste fijo: el servidor. Eso cambia completamente la ecuación económica cuando tienes flujos de alto volumen o datos sensibles que no quieres que pasen por servidores de terceros.
¿Qué es n8n y por qué self-hosted?
n8n (pronunciado "n-eight-n") es un motor de flujos de trabajo basado en nodos. Cada nodo representa una acción: llamar a una API, transformar datos, enviar un email, escribir en una base de datos, ejecutar código JavaScript… Los nodos se encadenan visualmente en un editor drag-and-drop y el motor los ejecuta en orden (o en paralelo, según el flujo).
El modelo fair-code significa que el código fuente es público y puedes desplegarlo gratis, pero no puedes usarlo como SaaS competidor de n8n Inc. Para la mayoría de empresas y freelancers, esto es irrelevante: simplemente lo instalas y lo usas.
¿Por qué self-hosted frente a n8n Cloud (o Zapier/Make)?
- Coste fijo: Un VPS de 10–20 $/mes corre miles de ejecuciones diarias. Con Zapier Business pagas ~0,02–0,05 $ por tarea; con 50.000 tareas/mes son 1.000–2.500 $/mes.
- Control total del dato: Tus credenciales, datos de clientes y lógica de negocio no salen de tu infraestructura.
- Sin límites artificiales: n8n Cloud tiene límites de ejecuciones por plan; self-hosted solo está limitado por tu hardware.
- Personalización: Puedes crear nodos custom en Node.js, modificar timeouts, integrarte con servicios internos no accesibles desde Internet.
- Backups y disaster recovery: Tienes control directo sobre la base de datos y los archivos de configuración.
El trade-off es el mantenimiento: actualizaciones, backups y monitorización son responsabilidad tuya. Pero con Docker y un buen docker-compose, el proceso es muy manejable.
Instalación con Docker
La forma más rápida de probar n8n es con un solo comando Docker. Para producción, la configuración recomendada usa docker-compose con PostgreSQL como base de datos persistente.
Inicio rápido (solo para explorar)
# Levantar n8n con SQLite (solo para desarrollo local)
docker run -it --rm --name n8n -p 5678:5678 -v ~/.n8n:/home/node/.n8n n8nio/n8n:latest
# Abrir en el navegador
open http://localhost:5678
Con SQLite los datos se guardan en ~/.n8n. No uses esto en producción: SQLite no soporta el modo queue ni múltiples workers.
Producción: docker-compose con PostgreSQL
Para un despliegue real necesitas PostgreSQL, variables de entorno bien configuradas y volúmenes persistentes. Aquí un docker-compose.yml completo:
version: "3.8"
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
# Base de datos
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
# URL pública (necesaria para webhooks)
N8N_HOST: ${N8N_HOST}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: https://${N8N_HOST}/
# Cifrado de credenciales (¡no cambiar una vez configurado!)
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
# Configuración general
GENERIC_TIMEZONE: Europe/Madrid
N8N_LOG_LEVEL: info
N8N_METRICS: "true"
# Autenticación básica (o usa SSO en versiones enterprise)
N8N_BASIC_AUTH_ACTIVE: "true"
N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER}
N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
n8n_data:
El fichero .env correspondiente (nunca lo commitas):
POSTGRES_PASSWORD=una_contraseña_segura_aqui
N8N_HOST=n8n.tudominio.com
N8N_ENCRYPTION_KEY=genera_con_openssl_rand_hex_32
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=otra_contraseña_segura
Para generar la N8N_ENCRYPTION_KEY:
openssl rand -hex 32Levanta el stack con:
docker compose up -d
docker compose logs -f n8n # seguir logs en tiempo realTu primer workflow
Una vez dentro del editor, el flujo de trabajo más básico tiene tres nodos: un trigger, una transformación y una acción de salida. El editor es visual: arrastras nodos desde el panel lateral, los conectas con flechas y configuras cada uno en el panel derecho.
El flujo canónico de "hola mundo" para entender los conceptos:
- Manual Trigger: Dispara el flujo manualmente desde el editor. Útil para probar sin necesidad de un evento externo.
- Set: El nodo más usado para transformar datos. Define campos, renombra propiedades, combina datos de nodos anteriores.
- HTTP Request: Llama a cualquier API REST. Soporta todos los métodos HTTP, cabeceras, autenticación OAuth2/Basic/API Key, paginación automática y parseo de JSON/XML/HTML.
Conceptos clave del modelo de ejecución de n8n:
- Items: n8n procesa arrays de ítems. Si tu nodo HTTP recibe 50 registros, el siguiente nodo los procesa de forma individual (por defecto) o en lote.
- Branches: Puedes dividir el flujo con el nodo
IFoSwitchpara tomar caminos distintos según condiciones. - Merge: El nodo
Mergecombina los resultados de varias ramas de nuevo en un único flujo. - Error handling: Cada nodo tiene un output de error; puedes encadenarlo a un nodo que envíe alertas a Slack, email, etc.
El editor guarda cada ejecución con su entrada y salida por nodo. Esto hace que depurar sea trivial: haces clic en cualquier nodo de una ejecución pasada y ves exactamente qué datos entró y salió.
Webhooks: disparar flujos desde fuera
Los webhooks son la forma de integrar n8n con el mundo exterior: cuando Stripe confirma un pago, cuando GitHub abre un issue, cuando un formulario se envía, cuando tu propia app emite un evento… El nodo Webhook de n8n expone una URL única que cualquier servicio puede llamar vía HTTP.
Cada webhook tiene dos URLs:
- Test URL (
/webhook-test/{id}): solo activa mientras tienes el flujo abierto en el editor y pulsas "Listen for Test Event". Perfecta para probar. - Production URL (
/webhook/{id}): activa cuando el flujo está guardado y activado. Esta es la que configuras en servicios externos.
Ejemplo de llamada a un webhook desde curl:
# Disparar un webhook con datos JSON
curl -X POST https://n8n.tudominio.com/webhook/abc123-def456-ghi789 -H "Content-Type: application/json" -H "X-Secret-Token: mi_token_secreto" -d '{
"evento": "pago_confirmado",
"pedido_id": "ORD-2026-001",
"importe": 149.99,
"cliente": {
"email": "cliente@ejemplo.com",
"nombre": "Ana García"
}
}'
# Respuesta esperada (si el workflow está activo)
# {"message":"Workflow was started"}En el nodo Webhook puedes configurar:
- Método HTTP: GET, POST, PUT, PATCH, DELETE.
- Authentication: None, Basic Auth, Header Auth (para verificar el token secreto del ejemplo anterior).
- Response Mode: "On Received" (responde inmediatamente 200 y procesa en segundo plano) o "Last Node" (espera a que el flujo termine y devuelve el resultado).
- Binary data: Puede recibir archivos si configuras el Content-Type adecuado.
Credenciales y seguridad
n8n tiene un sistema de credenciales cifrado. Cuando configuras un nodo de Gmail, Slack, una base de datos o cualquier API externa, las credenciales se guardan cifradas en la base de datos usando la N8N_ENCRYPTION_KEY. Esto significa que:
- Las credenciales nunca aparecen en texto plano en los logs ni en los datos de ejecución.
- Puedes compartir flujos de trabajo entre entornos sin exponer tokens: el flujo referencia las credenciales por nombre, no por valor.
- Si alguien accede a tu base de datos, no puede leer las credenciales sin la clave de cifrado.
Reglas de seguridad fundamentales:
- Genera la
N8N_ENCRYPTION_KEYantes del primer arranque y guárdala en un gestor de secretos (1Password, Vault, AWS Secrets Manager). Si la pierdes o la cambias, todas las credenciales almacenadas quedan inutilizables. - No hardcodees credenciales en los nodos: Usa siempre el sistema de credenciales. Los valores hardcodeados en un nodo "Set" o "HTTP Request" sí aparecen en los datos de ejecución.
- Restringe el acceso por IP a la instancia n8n si es posible. El editor no debería ser público.
- Usa variables de entorno para secretos de configuración (contraseñas de BD,
N8N_ENCRYPTION_KEY). Nunca los pongas en eldocker-compose.ymldirectamente — usa un fichero.envexcluido del control de versiones.
Para acceder a variables de entorno dentro de los flujos, n8n expone la función $env.NOMBRE_VARIABLE en las expresiones. Esto es útil para pasar configuración dinámica sin hardcodearla en los nodos.
Llevarlo a producción
El docker-compose de la sección anterior es un buen punto de partida, pero para producción real hay varios aspectos críticos que debes cubrir.
HTTPS y reverse proxy
n8n debe estar detrás de un reverse proxy que gestione TLS. Sin HTTPS los webhooks de muchos servicios (Stripe, GitHub, etc.) no funcionan, y tus credenciales viajarían en texto plano.
La solución más habitual con Docker es Traefik o Caddy. Caddy es especialmente sencillo porque gestiona los certificados Let's Encrypt de forma automática:
# Añadir al docker-compose.yml
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config# Caddyfile
n8n.tudominio.com {
reverse_proxy n8n:5678
}Backups de PostgreSQL
n8n almacena en PostgreSQL los workflows, credenciales cifradas, historial de ejecuciones y usuarios. Un backup periódico es imprescindible:
# Backup manual de la base de datos
docker exec n8n-postgres-1 pg_dump -U n8n n8n | gzip > n8n_backup_$(date +%Y%m%d_%H%M%S).sql.gz
# Restaurar desde backup
gunzip -c n8n_backup_20260615_120000.sql.gz | docker exec -i n8n-postgres-1 psql -U n8n n8nQueue mode: escalar a múltiples workers
Por defecto n8n ejecuta los flujos en el mismo proceso que el editor (modo "regular"). Para cargas de trabajo altas, el queue mode separa el proceso principal (editor + API) de los workers que ejecutan los flujos, usando Redis como cola de mensajes.
En queue mode puedes escalar horizontalmente añadiendo más workers sin tocar el proceso principal. La activación requiere añadir Redis al stack y configurar la variable EXECUTIONS_MODE=queue, más un servicio worker adicional con n8n worker como comando. La guía completa de este setup está en el PDF.
La guía completa
Este post cubre la base para arrancar con n8n self-hosted. La guía en PDF profundiza en todo lo que necesitas para un despliegue robusto y los flujos de trabajo que realmente ahorran tiempo:
- docker-compose endurecido: configuración completa de seguridad, límites de recursos, healthchecks, restart policies y variables de entorno documentadas.
- Queue mode con Redis paso a paso: arquitectura, configuración del worker, escalado horizontal y monitorización de la cola.
- 10 workflows reutilizables: notificaciones de Stripe a Slack, sincronización de contactos CRM, generación automática de facturas, alertas de uptime, procesamiento de formularios con validación, y más — listos para importar.
- Backups automatizados: script de cron para dumps nocturnos de PostgreSQL con rotación y subida a S3/R2.
- Troubleshooting: los 10 problemas más comunes (credenciales inutilizables tras cambio de key, webhooks que no llegan, ejecuciones colgadas, problemas de memoria) con su solución paso a paso.