Configuración Avanzada de n8n para Automatización de Workflows

n8n es una plataforma de automatización de workflows de código abierto con más de 400 integraciones que permite conectar servicios, transformar datos y crear flujos de trabajo complejos mediante una interfaz visual de nodos. Para entornos de producción, la configuración avanzada de n8n incluye el modo queue con workers distribuidos, gestión segura de credenciales, manejo de errores, sub-workflows y escalado horizontal. Esta guía cubre todo lo necesario para ejecutar n8n en producción en Linux.

Requisitos Previos

  • Linux con Docker y Docker Compose
  • 1 GB RAM mínimo (2 GB recomendado para producción)
  • PostgreSQL (recomendado sobre SQLite para producción)
  • Redis (necesario para el modo queue)
  • Dominio con SSL

Instalación en Producción con Docker

# /opt/n8n/docker-compose.yml
version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: password-seguro-postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass password-seguro-redis
    restart: unless-stopped

  n8n:
    image: n8nio/n8n:latest
    ports:
      - "127.0.0.1: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: password-seguro-postgres
      
      # Cifrado de credenciales (clave secreta)
      N8N_ENCRYPTION_KEY: clave-de-32-caracteres-minimo-aqui
      
      # URL pública
      N8N_HOST: n8n.tudominio.com
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://n8n.tudominio.com/
      
      # Autenticación básica del panel
      N8N_BASIC_AUTH_ACTIVE: "true"
      N8N_BASIC_AUTH_USER: admin
      N8N_BASIC_AUTH_PASSWORD: AdminPassword123!
      
      # Logs
      N8N_LOG_LEVEL: info
      N8N_LOG_OUTPUT: console,file
      N8N_LOG_FILE_LOCATION: /home/node/.n8n/logs/n8n.log
      
      # Ejecuciones
      EXECUTIONS_DATA_SAVE_ON_ERROR: all
      EXECUTIONS_DATA_SAVE_ON_SUCCESS: none  # Solo guardar errores para ahorrar espacio
      EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS: "true"
      EXECUTIONS_DATA_MAX_AGE: 168  # Conservar ejecuciones 7 días (en horas)
      
      # Zona horaria
      TZ: Europe/Madrid
      GENERIC_TIMEZONE: Europe/Madrid
      
    volumes:
      - n8n_data:/home/node/.n8n
      - /opt/n8n/local-files:/files  # Para acceso a archivos locales
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped

volumes:
  postgres_data:
  n8n_data:
cd /opt/n8n
docker compose up -d
docker compose logs n8n -f

# Nginx con SSL para n8n
cat > /etc/nginx/sites-available/n8n << 'EOF'
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://127.0.0.1:5678;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;
    }
}
EOF

ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d n8n.tudominio.com

Gestión de Credenciales

n8n cifra todas las credenciales con la N8N_ENCRYPTION_KEY. Las credenciales se crean una vez y se reutilizan en múltiples workflows:

Crear credenciales via API

N8N_URL="https://n8n.tudominio.com"
N8N_USER="admin"
N8N_PASS="AdminPassword123!"

# Obtener cookies de sesión (n8n usa autenticación de sesión)
curl -s -c cookies.txt -X POST "$N8N_URL/rest/login" \
    -H "Content-Type: application/json" \
    -d "{\"email\":\"$N8N_USER\",\"password\":\"$N8N_PASS\"}" | jq '.'

# Crear credencial de Slack
curl -s -b cookies.txt -X POST "$N8N_URL/rest/credentials" \
    -H "Content-Type: application/json" \
    -d '{
        "name": "Slack Produccion",
        "type": "slackApi",
        "data": {
            "accessToken": "xoxb-tu-token-de-slack"
        }
    }' | jq '.id'

# Crear credencial de base de datos PostgreSQL
curl -s -b cookies.txt -X POST "$N8N_URL/rest/credentials" \
    -H "Content-Type: application/json" \
    -d '{
        "name": "PostgreSQL Produccion",
        "type": "postgres",
        "data": {
            "host": "db.tudominio.com",
            "port": 5432,
            "database": "mi_app",
            "user": "n8n_user",
            "password": "db-password"
        }
    }'

# Listar todas las credenciales
curl -s -b cookies.txt "$N8N_URL/rest/credentials" | jq '.data[] | {id, name, type}'

Webhook Triggers y Endpoints

n8n puede recibir peticiones HTTP para disparar workflows:

Configurar un Webhook Trigger

En el workflow, agrega un nodo Webhook:

  • HTTP Method: POST (o GET, PUT, etc.)
  • Path: mi-webhook (genera URL: https://n8n.tudominio.com/webhook/mi-webhook)
  • Response Mode: Last Node o Immediately
# Probar el webhook con curl
curl -X POST https://n8n.tudominio.com/webhook/mi-webhook \
    -H "Content-Type: application/json" \
    -d '{
        "evento": "nuevo_pedido",
        "pedido_id": 12345,
        "total": 150.00
    }'

# Para webhooks que requieren autenticación:
# En el nodo Webhook > Authentication > Header Auth
# Header: X-Webhook-Secret
# Value: mi-secreto-compartido

curl -X POST https://n8n.tudominio.com/webhook/mi-webhook \
    -H "X-Webhook-Secret: mi-secreto-compartido" \
    -H "Content-Type: application/json" \
    -d '{"evento": "test"}'

Webhook con respuesta personalizada

// Nodo Respond to Webhook para enviar respuesta personalizada
// Configurar "Response Mode: Last Node" en el nodo Webhook

// En el último nodo del workflow:
{
  "statusCode": 200,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "status": "ok",
    "message": "Pedido procesado correctamente",
    "orderId": "{{$json.pedido_id}}"
  }
}

Manejo de Errores

Workflows de manejo de errores globales

# n8n permite definir un workflow que se ejecuta cuando otro falla
# Settings > Error Workflow: seleccionar el workflow de gestión de errores

Crea un workflow llamado "Manejo de Errores Global":

Trigger: Error Trigger
  ↓
Nodo Code: Preparar mensaje de error
  ↓
Nodo Slack/Email: Notificar al equipo
  ↓
Nodo HTTP: Enviar a sistema de tickets (opcional)
// Nodo Code para preparar el mensaje de error
const error = $input.all()[0].json;

return [{
    json: {
        titulo: `Error en workflow: ${error.workflow.name}`,
        descripcion: error.execution.error.message,
        workflowId: error.workflow.id,
        executionId: error.execution.id,
        timestamp: new Date().toISOString(),
        url: `https://n8n.tudominio.com/workflow/${error.workflow.id}/executions/${error.execution.id}`
    }
}];

Try/Catch en workflows

Nodo A (puede fallar)
  ↓ (en éxito)    ↗ (en error - conectar al nodo de error)
Nodo B           Nodo de manejo de error

En cada nodo que puede fallar:

  1. Clic derecho en el nodo > Settings
  2. Activar Continue On Fail
  3. El nodo de error tendrá el error en $json.error

Sub-workflows y Reutilización

Los sub-workflows permiten reutilizar lógica entre workflows:

Crear un sub-workflow

  1. Crea un workflow nuevo con el nodo Execute Workflow Trigger como inicio
  2. Define los parámetros de entrada
// En el nodo Execute Workflow Trigger del sub-workflow:
// Define qué datos espera recibir
// Los datos se acceden con $input.first().json

// Ejemplo: sub-workflow que envía email con retry
const { destinatario, asunto, cuerpo } = $input.first().json;

// Procesamiento...
return [{ json: { enviado: true, timestamp: new Date() } }];

Llamar a un sub-workflow

En el workflow principal, usa el nodo Execute Sub-workflow:

// Configuración del nodo Execute Sub-workflow:
// - Workflow ID: ID del sub-workflow a ejecutar
// - Input Data: datos a pasar al sub-workflow

// Pasar datos dinámicamente
{
    "destinatario": "{{ $json.email }}",
    "asunto": "Notificación de {{ $json.tipo }}",
    "cuerpo": "{{ $json.mensaje }}"
}

Modo Queue para Producción

El modo queue usa Redis para distribuir ejecuciones entre múltiples workers:

# docker-compose.yml con modo queue

  n8n-main:
    image: n8nio/n8n:latest
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      # Modo queue
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379
      QUEUE_BULL_REDIS_PASSWORD: password-seguro-redis
      # El proceso principal maneja la UI pero no ejecuta workflows
      N8N_DISABLE_PRODUCTION_MAIN_PROCESS: "false"
      # Variables comunes...
    command: n8n start

  n8n-worker-1:
    image: n8nio/n8n:latest
    environment:
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379
      QUEUE_BULL_REDIS_PASSWORD: password-seguro-redis
      N8N_ENCRYPTION_KEY: clave-de-32-caracteres-minimo-aqui
      DB_TYPE: postgresdb
      # ... mismo DB que el proceso principal
    command: n8n worker --concurrency=10
    depends_on:
      - redis
      - postgres
    restart: unless-stopped
    # Escalar añadiendo más workers:
    # docker compose up -d --scale n8n-worker-1=3
# Verificar que los workers están conectados
docker exec n8n-main n8n worker:info

# Ver las colas de Redis
docker exec redis redis-cli -a password-seguro-redis KEYS "bull:*"

Solución de Problemas

Los webhooks no reciben peticiones

# Verificar que la URL de webhook es accesible
curl -I https://n8n.tudominio.com/webhook/mi-webhook

# Verificar WEBHOOK_URL en la configuración
docker exec n8n-main env | grep WEBHOOK_URL

# El webhook solo funciona cuando el workflow está activo (toggle en ON)
# Los webhooks de prueba usan la ruta /webhook-test/

Error de credenciales cifradas

# Si cambias N8N_ENCRYPTION_KEY, las credenciales existentes no se pueden descifrar
# NUNCA cambies la clave de cifrado después de crear credenciales

# Para migrar credenciales a una nueva instancia:
# 1. Exportar workflows (incluye referencias a credenciales pero NO los secretos)
# 2. Las credenciales deben recrearse manualmente en la nueva instancia

# Verificar que la clave está correctamente configurada
docker exec n8n-main env | grep N8N_ENCRYPTION_KEY

Workflows lentos o que no terminan

# Ver ejecuciones activas
curl -b cookies.txt https://n8n.tudominio.com/rest/executions?status=running | jq '.'

# Ver el uso de recursos del contenedor
docker stats n8n-main

# Aumentar el timeout de ejecución
# Agregar al docker-compose.yml:
# EXECUTIONS_TIMEOUT: 3600  # 1 hora en segundos
# EXECUTIONS_TIMEOUT_MAX: 7200  # máximo permitido

# Cancelar una ejecución atascada
curl -b cookies.txt -X POST \
    https://n8n.tudominio.com/rest/executions/stop/EXECUTION_ID

Base de datos llena de ejecuciones antiguas

# Configurar limpieza automática
# En docker-compose.yml:
# EXECUTIONS_DATA_MAX_AGE: 72  # eliminar ejecuciones de más de 72 horas
# EXECUTIONS_DATA_PRUNE: "true"

# Limpiar manualmente ejecuciones antiguas
docker exec n8n-main n8n execute --command=pruneExecutionData

Conclusión

n8n en modo producción con PostgreSQL, Redis y workers distribuidos proporciona una plataforma de automatización robusta capaz de manejar miles de ejecuciones diarias sin pérdida de datos. La combinación de credenciales cifradas centralizadas, manejo de errores global, sub-workflows reutilizables y el modo queue para escalado horizontal hace que n8n sea adecuado para automatizaciones críticas de negocio, no solo para tareas simples de integración entre servicios.