Probado con n8n 2.39.6 · PostgreSQL 18.6 · Redis 8.10 · Docker Compose 2.40 · verificado

Actualizado: 2026-09-16

n8n es una plataforma de automatización low-code con unas 204 600 estrellas en GitHub a 16 de septiembre de 2026. Ofrece una alternativa seria a Zapier y Make para organizaciones que quieren controlar sus propios flujos sin pagar por cada ejecución. Este artículo instala n8n 2.39.6, la versión estable de esa fecha, con Docker Compose y PostgreSQL 18. También repasa las decisiones de arquitectura y los puntos donde vas a tropezar la primera vez; hemos ejecutado todos los comandos ese mismo día.

Puntos clave

  • Fija la versión de la imagen: n8nio/n8n:2.39.6 es la estable desde el 16 de septiembre de 2026, y la 2.40.1 sigue en beta.

  • Empieza con PostgreSQL 17 o 18: n8n 2.0 retiró MySQL y MariaDB como base de datos, y el modo queue sobre SQLite no está soportado.

  • El código de los nodos Code se ejecuta en task runners; en producción, llévalos a un contenedor n8nio/runners de la misma versión.

  • N8N_ENCRYPTION_KEY es la variable más crítica: genérala una vez, guárdala junto a las copias de la base de datos y no la cambies nunca.

  • Detrás de un proxy, los webhooks públicos necesitan N8N_WEBHOOK_URL con el dominio real; WEBHOOK_URL está obsoleta desde n8n 2.35.0.

Qué hace n8n y cuándo compensa auto-alojarlo

n8n permite conectar herramientas mediante flujos visuales donde cada nodo es una acción, un disparador o una transformación. Hay nodos para cientos de servicios comunes: Google Workspace, Slack, bases de datos, APIs HTTP genéricas, colas de mensajes, WhatsApp, correo, almacenamiento de objetos. Cuando no hay nodo, un nodo de código permite escribir JavaScript o Python para hacer casi cualquier cosa.

El proyecto es de código disponible desde su repositorio principal en GitHub[1], con la imagen oficial publicada en Docker Hub[2]. n8n creó en 2022 la Sustainable Use License, un modelo fair-code. Permite usar y modificar el código para uso interno o no comercial, pero restringe revenderlo como servicio competidor (detalle de la licencia[3]). Los ficheros con .ee. en el nombre requieren una licencia Enterprise.

Auto-alojarlo compensa sobre todo por tres razones:

  • Control de datos sensibles: si tus flujos mueven datos de clientes, contratos o datos financieros, tenerlos saltando entre un SaaS externo y tus sistemas internos supone una exposición que no todas las organizaciones aceptan.

  • Coste: la versión auto-alojada no cobra por ejecución de flujo, lo que para volúmenes altos es un ahorro sustancial frente a las alternativas comerciales.

  • Flexibilidad: integrar con sistemas internos, con APIs privadas o con bases de datos locales es mucho más fácil cuando n8n corre dentro de la misma red.

Donde no compensa es cuando los flujos son pocos y sencillos, con pocas integraciones externas y volumen bajo. En ese escenario la fricción operativa de mantener otra pieza de infraestructura supera el ahorro económico.

Qué versión de n8n instalar en septiembre de 2026

Instala la rama 2.x estable y fija el número exacto. La versión 2.0.0[4] salió el 8 de diciembre de 2025. El 16 de septiembre de 2026, GitHub marca la 2.39.6[5] como Latest y la 2.40.1 como Pre-release. Desde 2.0, los canales se llaman stable y beta, y n8n recomienda fijar la versión (cambios incompatibles de n8n 2.0[6]).

n8n prevé publicar n8n 3.0 en octubre de 2026[7], y solo admitirá instalaciones auto-alojadas con Docker. Si ya tienes una instancia 2.x, sigue la guía para preparar tu n8n autoalojado para n8n 3.0 antes de actualizar.

Instalación con Docker Compose y PostgreSQL

La instalación consta de tres contenedores: PostgreSQL, n8n y los task runners, y la probamos con Docker Engine 29.5.2 y Compose 2.40.3 en linux/arm64. Parte del ejemplo withPostgres del repositorio n8n-hosting[8], porque la guía oficial con Docker Compose[9] usa SQLite y añade el sandbox de n8n Assistant.

Primero, crea el directorio y el fichero .env con los secretos, generados con openssl:

mkdir -p ~/n8n && cd ~/n8n
cat > .env <<EOF
N8N_VERSION=2.39.6
N8N_DOMAIN=n8n.example.com
POSTGRES_PASSWORD=$(openssl rand -hex 24)
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
N8N_RUNNERS_AUTH_TOKEN=$(openssl rand -hex 32)
EOF
chmod 600 .env

Sustituye n8n.example.com por tu subdominio y guarda una copia de .env fuera del servidor. Después, crea compose.yaml en el mismo directorio:

services:
  postgres:
    image: postgres:18.6
    restart: unless-stopped
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: n8n
    volumes:
      - db_data:/var/lib/postgresql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    image: n8nio/n8n:${N8N_VERSION}
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_HOST: ${N8N_DOMAIN}
      N8N_PROTOCOL: https
      N8N_WEBHOOK_URL: https://${N8N_DOMAIN}/
      N8N_PROXY_HOPS: 1
      GENERIC_TIMEZONE: Europe/Madrid
      TZ: Europe/Madrid
      N8N_RUNNERS_MODE: external
      N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
      N8N_RUNNERS_BROKER_LISTEN_ADDRESS: 0.0.0.0
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

  n8n-runner:
    image: n8nio/runners:${N8N_VERSION}
    restart: unless-stopped
    environment:
      N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
      N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
    depends_on:
      - n8n

volumes:
  db_data:
  n8n_data:

PostgreSQL 18 guarda los datos en /var/lib/postgresql/18/docker, así que el volumen se monta en /var/lib/postgresql, como indica la documentación de la imagen oficial[10]. El puerto 5678 solo se publica en el 127.0.0.1 del host, porque el proxy inverso expondrá n8n. El servicio n8n-runner ejecuta el código de los nodos Code fuera del proceso de n8n, con la misma versión.

Arranca el stack y comprueba el estado:

docker compose up -d
docker compose ps --format 'table {{.Service}}\t{{.Image}}\t{{.Status}}'
SERVICE      IMAGE                  STATUS
n8n          n8nio/n8n:2.39.6       Up 7 seconds
n8n-runner   n8nio/runners:2.39.6   Up 7 seconds
postgres     postgres:18.6          Up 13 seconds (healthy)

En el primer arranque, n8n aplica 263 migraciones. El editor quedó listo 3,5 s después de arrancar el contenedor con una carga media de 4 en 18 núcleos, y 6,9 s con una carga de 37. Los logs confirman la versión, la URL pública y los runners de JavaScript y Python:

docker compose logs --no-log-prefix n8n | grep -E -A1 'Version:|Editor is now'
docker compose logs --no-log-prefix n8n | grep 'Registered runner'
docker compose exec n8n wget -qO- http://127.0.0.1:5678/healthz/readiness
Version: 2.39.6
Building workflow dependency index...
--
Editor is now accessible via:
https://n8n.example.com
Registered runner "launcher-javascript" (d991bbc56f76e9b3)
Registered runner "launcher-python" (984bc6c61fb5eeea)
{"status":"ok"}

Con el proxy listo, abre https://n8n.example.com y crea la cuenta de propietario. En la prueba no había dominio, así que creamos la cuenta con la API REST local en vez de con el formulario.

La elección de base de datos

La base de datos guarda flujos, credenciales, historial de ejecución y usuarios. Desde n8n 2.0 solo quedan SQLite, la opción por defecto, y PostgreSQL, porque esa versión retiró MySQL y MariaDB.

La recomendación, para casi cualquier despliegue que vaya a tener más de un flujo o más de un usuario, es empezar directamente con PostgreSQL. La documentación de n8n[11] admite PostgreSQL 17 y 18, más la 16 por compatibilidad. Pasar de SQLite a PostgreSQL después es posible con n8n export:entities e import:entities, pero incómodo, y las ventajas de PostgreSQL aparecen incluso en escalas pequeñas:

  • Mejores copias de seguridad.

  • Introspección más clara.

  • Posibilidad de activar modo queue más adelante sin volver a migrar.

Si ya tienes un PostgreSQL compartido, puedes usarlo creando una base de datos dedicada para n8n. Esto reduce el número de contenedores y simplifica los respaldos. Quien ya gestione ese Postgres con Docker Compose puede apoyarse en la guía de instalación de Docker Compose en Ubuntu 20.04 para dejar ambos servicios definidos en el mismo stack.

Ojo con la ruta del volumen en PostgreSQL 18. El ejemplo de n8n lo monta en /var/lib/postgresql/data y fija PGDATA en esa ruta; sin esa variable, la base queda fuera del volumen y el contenedor recreado arranca vacío. La guía de PostgreSQL con Docker explica el resto de opciones.

El modo queue para cargas serias

Por defecto, n8n ejecuta flujos en el mismo proceso que sirve la interfaz web. Este modo es suficiente para volúmenes bajos, pero cuando hay flujos largos o una concurrencia alta aparecen problemas: la interfaz se ralentiza, las ejecuciones pueden bloquearse y no hay forma de escalar horizontalmente.

La solución es el modo queue, descrito en la guía oficial del modo queue[12]. El proceso principal deja cada ejecución en una cola Redis, y un worker la recoge, la ejecuta y guarda el resultado en PostgreSQL. Cada worker acepta 10 trabajos simultáneos por defecto. Para activarlo, añade compose.queue.yaml junto al fichero anterior:

services:
  redis:
    image: redis:8.10.1
    restart: unless-stopped

  n8n:
    environment: &queue
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: "true"
    depends_on: [redis]

  n8n-worker:
    extends: {file: compose.yaml, service: n8n}
    command: worker
    environment: *queue
    ports: !reset []
    volumes: !reset []
    depends_on: [redis]

  n8n-worker-runner:
    extends: {file: compose.yaml, service: n8n-runner}
    environment:
      N8N_RUNNERS_TASK_BROKER_URI: http://n8n-worker:5679
    depends_on: [n8n-worker]

El worker hereda con extends la configuración de n8n, incluida la misma N8N_ENCRYPTION_KEY. La etiqueta !reset (reglas de fusión de Compose[13]) le quita el puerto y el volumen, para que no comparta el log de eventos con el proceso principal. Cada worker necesita además su propio contenedor de runners. Arranca los dos ficheros juntos y comprueba que el worker está listo:

export COMPOSE_FILE=compose.yaml:compose.queue.yaml
docker compose up -d
docker compose logs --no-log-prefix n8n-worker | grep -A4 'worker is now ready'
n8n worker is now ready
 * Version: 2.39.6
 * Concurrency: 10
 * Pool: (default)
 * Queue: jobs

Con un flujo de prueba publicado, el worker registró Worker started execution 1 (job 1) y Worker finished execution 1 (job 1). OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true manda también las ejecuciones manuales a los workers, como hará siempre n8n 3.0. Los datos binarios no pueden ir al sistema de ficheros en modo queue: usa la base de datos o S3.

Variables de entorno críticas

Hay unas pocas variables de entorno que conviene configurar correctamente desde el principio:

  • N8N_ENCRYPTION_KEY: la clave usada para cifrar credenciales en la base de datos. Si esta clave cambia, todas las credenciales almacenadas quedan inutilizables. Genérala una vez con openssl rand -hex 32, guárdala en lugar seguro y no la cambies nunca.

  • N8N_HOST, N8N_WEBHOOK_URL y N8N_PROXY_HOPS: dicen a n8n su dominio, la URL de los webhooks públicos y cuántos proxies tiene delante (configuración con proxy inverso[14]). La antigua WEBHOOK_URL está obsoleta desde la 2.35.0, y en la prueba el log avisó: Use N8N_WEBHOOK_URL instead. El error típico es olvidar la URL pública detrás de Traefik y dejar los webhooks apuntando a localhost.

  • N8N_RUNNERS_MODE y N8N_RUNNERS_AUTH_TOKEN: desde n8n 2.0 los task runners están activos por defecto, y el log de 2.39.6 pide retirar N8N_RUNNERS_ENABLED. El log también marca como obsoleto el modo interno, que lanza los runners como procesos hijos de n8n, y la documentación de task runners[15] lo desaconseja en producción. Con N8N_RUNNERS_MODE=external, el contenedor n8nio/runners se conecta al puerto 5679 con el token compartido.

Traefik o Nginx por delante

En una instalación auto-alojada, n8n suele correr detrás de un proxy como Traefik o Nginx para manejar HTTPS y para servir más de un servicio en el mismo servidor. La configuración del proxy es estándar: un router apuntando al puerto 5678 del contenedor n8n, con certificado TLS automático y las cabeceras X-Forwarded-*. Quien todavía no tenga el proxy montado puede seguir la guía de instalación de Traefik con Docker Compose, que usa la misma sintaxis de Docker Compose[16] que este artículo.

Un detalle a cuidar es el tiempo límite del proxy. Algunos flujos pueden tardar minutos en ejecutarse, sobre todo si llaman a APIs externas lentas o procesan archivos grandes. El proxy_read_timeout de Nginx[17] vale 60 s por defecto y puede cortar estas ejecuciones con errores 504 Gateway Timeout. Conviene subirlo a minutos, no segundos, para las rutas de ejecución de flujos.

Para webhooks públicos hay que prestar atención a que la URL pública sea accesible desde internet. Un error común es tener n8n en una red interna detrás de VPN, poner un webhook en un flujo y no entender por qué no llega. El servicio externo no puede alcanzar la URL que n8n genera.

Puntos de fricción típicos

Cuatro problemas que casi todo el mundo encuentra la primera vez:

  • Persistencia de datos: el contenedor de n8n guarda datos en /home/node/.n8n, que debe ir en un volumen persistente. Más de un equipo ha perdido flujos y credenciales por ejecutar docker compose down -v, que borra los volúmenes. La recomendación es usar volúmenes nombrados y tener copias de seguridad regulares de la base de datos.

  • Manejo de credenciales: n8n cifra las credenciales con N8N_ENCRYPTION_KEY, pero el proceso de backup debe incluir tanto la base de datos como la clave de cifrado. Si restauras la base en otro servidor con una clave distinta, todas las credenciales son inútiles. Guarda siempre las dos piezas juntas.

  • Publicar en lugar de activar: n8n 2.0 cambió el interruptor activo/inactivo por los botones Publish y Unpublish, y los cambios quedan en borrador hasta que publicas (guardar y publicar flujos[18]). n8n publish:workflow exige reiniciar n8n, y en la prueba n8n import:workflow despublicó el flujo que sobrescribía. Revisa los flujos publicados después de importar en lote.

  • Código que deja de funcionar en el nodo Code: los runners aíslan ese código, y en la prueba process.version falló con process is not defined. Desde n8n 2.0, el nodo tampoco lee variables de entorno salvo con N8N_BLOCK_ENV_ACCESS_IN_NODE=false.

Para las copias de seguridad, estas dos órdenes funcionaron en la prueba. La primera vuelca PostgreSQL y la segunda exporta cada flujo a un JSON dentro del volumen de n8n:

docker compose exec -T postgres pg_dump -U n8n -Fc n8n > n8n-$(date +%F).dump
docker compose exec -u node n8n \
  n8n export:workflow --backup --output=/home/node/.n8n/backups/

Preguntas frecuentes

¿n8n es gratis para uso propio?

Sí. Bajo la Sustainable Use License puedes usar, modificar y auto-alojar n8n sin coste para uso interno o personal; lo que la licencia restringe es revenderlo como servicio SaaS competidor.

¿Cuándo conviene activar el modo queue?

Cuando las ejecuciones se acumulan o el editor se ralentiza bajo carga. En la prueba, el worker ocupó entre 252 y 458 MiB de RAM y Redis entre 9 y 43 MiB, poco comparado con migrar más tarde con datos en producción.

¿Qué pasa si pierdo la clave de cifrado?

Todas las credenciales guardadas en la base de datos quedan inutilizables y hay que volver a introducirlas una por una. Por eso N8N_ENCRYPTION_KEY debe respaldarse junto a la base de datos, nunca por separado.

¿Puedo usar MySQL o MariaDB como base de datos de n8n?

No desde n8n 2.0, que solo admite SQLite y PostgreSQL. Migra los datos antes de actualizar; el nodo MySQL para consultar tus propias bases sigue disponible.

Mi lectura

n8n es una herramienta que cumple bien su promesa: automatizaciones complejas sin tener que escribir mucho código, con control sobre los datos y sin tarifas por ejecución. Para organizaciones que encadenan sistemas internos y quieren mantener sus datos en casa, la versión auto-alojada es competitiva frente a cualquier alternativa comercial.

La recomendación concreta es que si estás evaluando Zapier o Make para uso serio en tu organización, mires n8n auto-alojado antes de decidir. Los requisitos son modestos: en la prueba, n8n osciló entre 264 y 872 MiB de RAM y PostgreSQL entre 35 y 45 MiB. Si dudas entre plataformas auto-alojadas, compáralo antes con Activepieces y Windmill.

Donde conviene parar y pensar es en el caso contrario. Si tus operaciones internas no acumulan integraciones ni datos sensibles, y solo necesitas pegar tres APIs externas comunes, la versión SaaS comercial sigue siendo más fácil de gestionar. Auto-alojar infraestructura siempre tiene coste operativo, y ese coste debe compensarse con beneficio real. n8n no es una excepción a esa regla general.

¿Prefieres leerlo en inglés? Aquí tienes la versión en inglés de este artículo.

Conclusión

La decisión de auto-alojar n8n se reduce a una pregunta: ¿el control de los datos y el ahorro en ejecuciones compensa el coste operativo de mantener otra pieza de infraestructura? Para volúmenes medios y datos sensibles, la respuesta suele ser sí.

Fuentes

  1. repositorio principal en GitHub
  2. Docker Hub
  3. detalle de la licencia
  4. versión 2.0.0
  5. 2.39.6
  6. cambios incompatibles de n8n 2.0
  7. n8n 3.0 en octubre de 2026
  8. repositorio n8n-hosting
  9. guía oficial con Docker Compose
  10. documentación de la imagen oficial
  11. documentación de n8n
  12. guía oficial del modo queue
  13. reglas de fusión de Compose
  14. configuración con proxy inverso
  15. documentación de task runners
  16. sintaxis de Docker Compose
  17. proxy_read_timeout de Nginx
  18. guardar y publicar flujos