Escribe algo para buscar...
n8n en Producción: Alta Disponibilidad con Docker, Redis y PostgreSQL

n8n en Producción: Alta Disponibilidad con Docker, Redis y PostgreSQL

Si ya tienes n8n funcionando con Docker en su configuración básica, sabes que es una herramienta poderosa. Pero cuando los flujos de trabajo se vuelven críticos para tu operación — automatizaciones que deben ejecutarse sin fallas, con concurrencia real y soporte para cargas altas — la instalación básica se queda corta.

En este post vamos a desplegar n8n en producción con una arquitectura diseñada para escalar: modo queue con Redis, múltiples workers, task runner externo y PostgreSQL como base de datos. Esta es la configuración que usamos en ECODING para nuestros flujos internos.

Prerequisito: Se recomienda haber leído el post anterior Instalación de n8n con Docker para entender los conceptos base antes de continuar.


¿Por qué esta arquitectura?

La instalación básica de n8n corre todo en un solo proceso: recibe los triggers, encola las ejecuciones y las procesa. Esto funciona bien para uso personal o equipos pequeños. Los problemas aparecen cuando:

  • Múltiples flujos se disparan al mismo tiempo y se bloquean entre sí
  • Un flujo pesado congela la interfaz web
  • Necesitas escalar horizontalmente sin bajar el servicio
  • La base de datos SQLite no aguanta la concurrencia

La solución es separar responsabilidades en componentes independientes:

┌─────────────────────────────────────────────────────┐
│                     backend-net                      │
│                                                      │
│  ┌──────────┐    ┌───────┐    ┌──────────────────┐  │
│  │  n8n     │───▶│ Redis │    │   PostgreSQL      │  │
│  │  (main)  │    │(queue)│    │   (persistencia)  │  │
│  └──────────┘    └───────┘    └──────────────────┘  │
│       │              │                               │
│       ▼              ▼                               │
│  ┌──────────────────────┐    ┌──────────────────┐   │
│  │   n8n-worker (x3)    │    │  n8n-task-runner │   │
│  │  concurrency=5 cada  │    │  (código JS/TS)  │   │
│  └──────────────────────┘    └──────────────────┘   │
└─────────────────────────────────────────────────────┘

Componentes de la arquitectura

n8n (proceso principal)

El proceso principal se encarga de:

  • Servir la interfaz web
  • Recibir webhooks y triggers
  • Encolar las ejecuciones en Redis (no ejecutarlas directamente)
  • Coordinar los workers

n8n-worker

Procesos independientes cuya única función es tomar trabajos de la cola Redis y ejecutarlos. Al tener 3 réplicas con concurrencia de 5 cada una, tienes capacidad para 15 ejecuciones simultáneas. Puedes ajustar ambos números según tu carga.

n8n-task-runner

Componente relativamente nuevo en n8n: ejecuta el código JavaScript/TypeScript de los nodos “Code” en un proceso aislado, separado del worker. Esto tiene dos ventajas clave:

  • Seguridad: el código de usuario no corre dentro del proceso principal de n8n
  • Estabilidad: si un script falla o consume demasiada memoria, no afecta al worker

Redis

Actúa como broker de cola (Bull queue). El proceso principal deposita trabajos ahí y los workers los consumen. También persiste el estado de ejecuciones en curso.

PostgreSQL

Reemplaza a SQLite como base de datos principal. Indispensable cuando tienes múltiples workers accediendo concurrentemente al mismo estado.


Preparación previa

Antes de levantar el stack, necesitas crear la red y el volumen externos. Solo se hace una vez por servidor:

docker network create backend-net
docker volume create n8n_data

La red backend-net es compartida con otros servicios (Redis, PostgreSQL). Esto permite que los contenedores se comuniquen entre sí por nombre de host sin exponer puertos al host.

Si ya tienes Redis y PostgreSQL corriendo en esta red desde otros stacks, solo asegúrate de que el nombre de red coincida.


El docker-compose.yml

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    user: node
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      # Identidad del servicio
      - N8N_HOST=tu-dominio.com
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://tu-dominio.com/
      - N8N_PORT=5678
      - N8N_TRUST_PROXY=true
      - N8N_PROXY_HOPS=1

      # Zona horaria
      - TZ=America/Lima
      - GENERIC_TIMEZONE=America/Lima
      - NODE_ENV=production

      # Base de datos PostgreSQL
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n_db
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=TU_PASSWORD_SEGURO

      # Cola con Redis (modo queue)
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - QUEUE_BULL_REDIS_PASSWORD=TU_REDIS_PASSWORD
      - QUEUE_BULL_REDIS_DB=0

      # Task runner externo
      - N8N_RUNNERS_MODE=external
      - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
      - N8N_RUNNERS_AUTH_TOKEN=TU_TOKEN_SECRETO

      # Ejecuciones manuales también van a workers
      - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true

      # Almacenamiento de datos binarios
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
      - N8N_STORAGE_PATH=/home/node/.n8n/binaryData

      # Configuración de permisos
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true

      # SMTP (opcional, para notificaciones por email)
      - N8N_EMAIL_MODE=smtp
      - N8N_SMTP_HOST=TU_SMTP_HOST
      - N8N_SMTP_PORT=465
      - N8N_SMTP_USER=TU_SMTP_USER
      - N8N_SMTP_PASS=TU_SMTP_PASSWORD
      - N8N_SMTP_SENDER=noreply@tu-dominio.com
      - N8N_SMTP_SSL=true

      # Módulos Node.js adicionales (opcional)
      - N8N_NODE_MODULES_INCLUDE=cheerio

    volumes:
      - n8n_data:/home/node/.n8n

    networks:
      - backend-net

  n8n-worker:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    user: node
    command: worker --concurrency=5
    deploy:
      replicas: 3
    environment:
      - N8N_HOST=tu-dominio.com
      - N8N_PROTOCOL=https
      - TZ=America/Lima
      - GENERIC_TIMEZONE=America/Lima
      - NODE_ENV=production

      # Los workers también necesitan acceso a la base de datos
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n_db
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=TU_PASSWORD_SEGURO

      # Y a Redis para consumir la cola
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - QUEUE_BULL_REDIS_PASSWORD=TU_REDIS_PASSWORD
      - QUEUE_BULL_REDIS_DB=0

      # Almacenamiento binario compartido con el proceso principal
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
      - N8N_STORAGE_PATH=/home/node/.n8n/binaryData

    volumes:
      - n8n_data:/home/node/.n8n

    networks:
      - backend-net

  n8n-task-runner:
    image: n8nio/runners:latest
    restart: always
    environment:
      - N8N_RUNNERS_AUTH_TOKEN=TU_TOKEN_SECRETO
      - N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
    networks:
      - backend-net
    depends_on:
      - n8n

volumes:
  n8n_data:
    external: true

networks:
  backend-net:
    external: true

Análisis de las decisiones de configuración

Puerto solo en localhost

ports:
  - "127.0.0.1:5678:5678"

El puerto solo se expone en la interfaz de loopback del host. Esto significa que n8n no es accesible directamente desde internet — necesitas un reverse proxy (Nginx, Caddy, etc.) por delante. Es una buena práctica de seguridad: el reverse proxy se encarga de TLS y de filtrar tráfico antes de que llegue a la aplicación.

EXECUTIONS_MODE=queue

- EXECUTIONS_MODE=queue

Este es el cambio más importante. En modo regular (defecto), n8n ejecuta todo en el proceso principal. En modo queue, el proceso principal solo recibe y encola — los workers hacen el trabajo real. Esto desacopla la interfaz web de la ejecución de flujos.

Workers con réplicas y concurrencia

command: worker --concurrency=5
deploy:
  replicas: 3

Cada worker puede procesar 5 ejecuciones simultáneas (--concurrency=5). Con 3 réplicas tienes 15 ejecuciones paralelas en todo momento. Ajusta según tus necesidades:

  • Flujos simples y rápidos → más concurrencia, menos réplicas
  • Flujos pesados (mucha CPU/memoria) → menos concurrencia, más réplicas
  • Para empezar: replicas: 2, concurrency: 3 es razonable en un VPS pequeño

Nota: deploy.replicas funciona con Docker Swarm o Docker Compose v3. Si usas Compose standalone, levanta los workers manualmente con --scale n8n-worker=3.

OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS

- OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true

Por defecto, cuando ejecutas un flujo manualmente desde la interfaz (botón “Execute Workflow”), n8n lo corre en el proceso principal aunque estés en modo queue. Con esta variable, todas las ejecuciones — automáticas y manuales — pasan por los workers. Así el proceso principal nunca queda bloqueado.

Task Runner externo

- N8N_RUNNERS_MODE=external
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
- N8N_RUNNERS_AUTH_TOKEN=TU_TOKEN_SECRETO

El proceso principal actúa como broker en el puerto 5679 (interno, no expuesto). El contenedor n8n-task-runner se conecta a él para recibir tareas de ejecución de código. La autenticación se hace con el token compartido.

Para generar un token seguro:

openssl rand -hex 32

Almacenamiento binario en filesystem

- N8N_DEFAULT_BINARY_DATA_MODE=filesystem
- N8N_STORAGE_PATH=/home/node/.n8n/binaryData

Cuando los flujos manejan archivos (PDFs, imágenes, CSVs), n8n necesita almacenarlos temporalmente. En modo memory (defecto) se guardan en RAM — con múltiples workers y archivos grandes, esto puede agotar la memoria rápidamente. En modo filesystem se guardan en disco y se comparte el volumen n8n_data entre el proceso principal y todos los workers.

Redis en una base de datos separada

- QUEUE_BULL_REDIS_DB=0

Redis soporta múltiples bases de datos lógicas (0-15) en la misma instancia. Si compartes Redis con otras aplicaciones, cambia el número para aislar los datos de n8n. Por ejemplo, si otra app usa DB 0, puedes poner n8n en DB 3 y no habrá interferencia.

N8N_NODE_MODULES_INCLUDE

- N8N_NODE_MODULES_INCLUDE=cheerio

Por seguridad, n8n restringe qué módulos de Node.js pueden usarse en los nodos “Code”. Esta variable lista en blanco los módulos adicionales que quieres habilitar. cheerio es útil para parsear HTML. Puedes agregar múltiples módulos separados por coma: cheerio,lodash,axios.


Variables que debes personalizar

VariableDescripciónCómo obtenerlo
N8N_HOSTTu dominioEl dominio que apunta a tu servidor
WEBHOOK_URLURL base para webhookshttps://tu-dominio.com/
DB_POSTGRESDB_PASSWORDContraseña de PostgreSQLGenerar con openssl rand -base64 24
QUEUE_BULL_REDIS_PASSWORDContraseña de RedisGenerar con openssl rand -base64 24
N8N_RUNNERS_AUTH_TOKENToken para task runnerGenerar con openssl rand -hex 32
N8N_SMTP_*Configuración de correoDatos de tu proveedor SMTP
TZ / GENERIC_TIMEZONEZona horariaVer lista en Wikipedia

Levantar el stack

# 1. Crear red y volumen (solo la primera vez)
docker network create backend-net
docker volume create n8n_data

# 2. Levantar los servicios
docker compose up -d

# 3. Verificar que todo esté corriendo
docker compose ps

# 4. Ver logs del proceso principal
docker compose logs -f n8n

# 5. Ver logs de los workers
docker compose logs -f n8n-worker

Verificar que el modo queue funciona

Una vez levantado, entra a la interfaz web y ve a Settings → About. Deberías ver el modo de ejecución como queue. Si ves regular, revisa las variables de entorno.

Para verificar que los workers están conectados, ejecuta cualquier flujo simple y en los logs de n8n-worker deberías ver la ejecución siendo procesada.


Consideraciones para producción

  • Backups de PostgreSQL: Los datos críticos de n8n (flujos, credenciales, historial) están en PostgreSQL. Configura backups automáticos.
  • Persistencia de Redis: Si Redis se reinicia, las ejecuciones en cola se pierden. Considera habilitar AOF persistence en tu configuración de Redis.
  • Monitoreo: Agrega healthchecks a los contenedores y monitoreа el tamaño de la cola en Redis con LLEN bull:jobs:wait.
  • Escalado: Puedes agregar más workers en caliente con docker compose up --scale n8n-worker=5 -d sin reiniciar el proceso principal.

En los próximos posts de esta serie vamos a ver cómo configurar Redis y PostgreSQL con sus propios stacks de Docker, listos para conectarse a esta arquitectura y a otros servicios que vayas sumando.

Related Posts

Introducción al flujo de trabajo en GitHub

Introducción al flujo de trabajo en GitHub

El flujo de GitHub Además de ser una plataforma de desarrollo de software colaborativo, GitHub ofrece también un flujo de trabajo diseñado para optimizar el uso de sus diversas características. Au

leer más
Instalación de n8n con Docker: Guía Completa

Instalación de n8n con Docker: Guía Completa

En esta guía explicaremos cómo instalar n8n utilizando Docker, la forma recomendada para la mayoría de casos de uso. Docker proporciona un entorno aislado y limpio, evita incompatibilidades en

leer más
Descargue y configurar el servidor OpenVPN en Ubuntu

Descargue y configurar el servidor OpenVPN en Ubuntu

InstalaciónDescargar openvpn-install.sh💻 $ wget https://git.io/vpn -O openvpn-install.sh... Saving to: ‘openvpn-install.sh’ openvpn-install.sh 100%[====

leer más
Comandos de Git

Comandos de Git

Git es un sistema de control de versiones que permite a los desarrolladores colaborar en proyectos de software y mantener un historial de cambios en el código fuente. A continuación, se describen algu

leer más
Desplegando n8n en una VM de GCP con Cloudflare Tunnel

Desplegando n8n en una VM de GCP con Cloudflare Tunnel

En esta guía explico cómo instalar y exponer n8n en una máquina virtual de Google Cloud Platform (GCP) utilizando Cloudflare Tunnel. La idea es mantener la instancia lo más ligera posible,

leer más
Redis Self-Hosted con Docker: Caché y Colas para tus Servicios

Redis Self-Hosted con Docker: Caché y Colas para tus Servicios

Con PostgreSQL ya desplegado como base de datos persistente, el último componente de la infraestructura base es Redis. En el stack de [n8n en alta

leer más
Implementando SSO corporativo con Keycloak y OpenID Connect (paso a paso con un ejemplo práctico)

Implementando SSO corporativo con Keycloak y OpenID Connect (paso a paso con un ejemplo práctico)

El escenario: de auth legacy a SSO corporativo Partimos de una app interna de ejemplo:Nombre: secrets-admin URL: https://secrets-admin.example.com Tipo: aplicación web interna que gest

leer más
PostgreSQL Self-Hosted con Docker y pgvector: Base de Datos para tus Servicios

PostgreSQL Self-Hosted con Docker y pgvector: Base de Datos para tus Servicios

En la arquitectura de alta disponibilidad con n8n que vimos anteriormente, uno de los requisitos era reemplazar SQLite por una base de datos real. P

leer más
Descargar Nginx y configurar el Reverse Proxy en Ubuntu

Descargar Nginx y configurar el Reverse Proxy en Ubuntu

Paso 1: Actualizar repositorios Antes de comenzar, debemos asegurarnos de que los repositorios estén actualizados. Para ello, ejecutamos el siguiente comando en la terminal: sudo apt

leer más
Guía Completa del Servidor Hytale: Configuración y Administración

Guía Completa del Servidor Hytale: Configuración y Administración

Guía Completa del Servidor Hytale: Configuración y Administración ¿Quieres crear tu propio servidor de Hytale pero no sabes por dónde empezar? Esta guía te llevará paso a paso por todo lo que neces

leer más
Guía Completa de Markdown: Domina el Lenguaje de Marcado Ligero

Guía Completa de Markdown: Domina el Lenguaje de Marcado Ligero

¿Qué es Markdown? Markdown es un lenguaje de marcado ligero creado por John Gruber en 2004. Está diseñado para ser fácil de leer y escribir, utilizando una sintaxis de texto plano que se puede

leer más