Execução do workflow não funciona após publicação, todos ficam pendentes na fila [n8n auto-hospedado]

Descreva o problema/erro/pergunta

N8N foi instalado no Ubuntu, nginx foi configurado com proxy reverso.
Todos os meus workflows funcionam perfeitamente no modo Teste, como compartilhei aqui um leitor RSS muito simples, clique no botão e o workflow carregará o feed RSS remoto e exibirá pela primeira vez no formulário final.
Se eu testá-lo com URL de Teste, funciona conforme esperado. Mas se eu publicá-lo (ou qualquer outro workflow), quando executo a URL de Produção, depois de clicar no botão no primeiro Formulário, o botão fica carregando e nada acontece (o feed RSS do backend nunca é lido remotamente).
Na lista de Execuções, todos os meus workflows publicados têm status “Enfileirado”, os Iniciados são sempre “Iniciando em breve”, o Tempo de Execução continua aumentando e nunca termina.
Minha suposição é que algo bloqueia a execução de produção no backend do n8n. Obrigado por ajudar, estou preso aqui há 2 dias.

Esta captura de tela é quando executo o workflow no modo Teste, funciona perfeitamente.

Qual é a mensagem de erro (se houver)?

Esta captura de tela é após publicar o workflow, todas as execuções estão pendentes.

Por favor, compartilhe seu workflow

(Selecione os nós no seu canvas e use os atalhos de teclado CMD+C/CTRL+C e CMD+V/CTRL+V para copiar e colar o workflow.)
{
  "nodes": [
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e2ffe594-180d-4e1d-b869-8056ac67015d",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "87c5a171-9ab9-4043-a72a-32aec218fe63",
              "name": "pubDate",
              "type": "string",
              "value": "={{ $json.pubDate }}"
            },
            {
              "id": "978b05c9-6e6b-4a18-bc06-4de785b19413",
              "name": "conteudo",
              "type": "string",
              "value": "={{ $json.content }}"
            }
          ]
        },
        "options": {}
      },
      "id": "3bc80f1d-ba03-4e66-bc75-e191777196a0",
      "name": "Edit Fields3",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        320
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "maxItems": 10
      },
      "id": "5585ebb1-e06b-42e2-aa0a-4011e94ece3f",
      "name": "Limit",
      "type": "n8n-nodes-base.limit",
      "position": [
        928,
        320
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "url": "https://www.technologyreview.com/topic/artificial-intelligence/feed/",
        "options": {
          "ignoreSSL": false
        }
      },
      "id": "ecba6a40-44cb-4834-8927-aa87a55cca8f",
      "name": "My RSS 01",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        272,
        320
      ],
      "typeVersion": 1.1,
      "alwaysOutputData": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "30d4f694-9378-42b4-b1d5-cbc38fb3e7fe",
              "operator": {
                "type": "dateTime",
                "operation": "after"
              },
              "leftValue": "={{ $json.pubDate }}",
              "rightValue": "={{ $today.minus({ days: 1 }) }}"
            }
          ]
        },
        "options": {}
      },
      "id": "8fdb9e97-6046-437f-926b-8a9f4eaf3854",
      "name": "Filter1",
      "type": "n8n-nodes-base.filter",
      "position": [
        736,
        320
      ],
      "typeVersion": 2.2,
      "disabled": true
    },
    {
      "parameters": {
        "formTitle": "test",
        "formFields": {
          "values": [
            {
              "fieldLabel": "test",
              "placeholder": "aaaa",
              "defaultValue": "test",
              "requiredField": true
            }
          ]
        },
        "responseMode": "lastNode",
        "options": {
          "appendAttribution": false,
          "buttonLabel": "GO "
        }
      },
      "id": "d7998250-8903-4318-a44e-2bc4ec3fae38",
      "name": "On form submission",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        64,
        320
      ],
      "webhookId": "b1244062-414d-4635-94bb-3999d8ba7287",
      "typeVersion": 2.2
    },
    {
      "parameters": {
        "operation": "completion",
        "completionTitle": "={{ $json.title }}",
        "completionMessage": "={{ $json.conteudo }}",
        "options": {}
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 2.5,
      "position": [
        1136,
        320
      ],
      "id": "40f53bbb-dda0-4ab6-a47b-e656b9ce4ed0",
      "name": "Form",
      "webhookId": "ac0921e8-ef8d-4d19-bbf5-601072cd36d6"
    }
  ],
  "connections": {
    "Edit Fields3": {
      "main": [
        [
          {
            "node": "Filter1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit": {
      "main": [
        [
          {
            "node": "Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "My RSS 01": {
      "main": [
        [
          {
            "node": "Edit Fields3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter1": {
      "main": [
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "My RSS 01",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "d3bbdc95153e6946dbacaffe72cbd2c695d3923240e6e037f8990bdb0f62c236"
  }
}

Compartilhe a saída retornada pelo último nó

Este é meu arquivo docker compose para implantação de n8n, n8n-runner, postgres, redis e nginx.

services:
    postgres:
        image: postgres:16-alpine
        container_name: n8n-postgres
        hostname: n8n-postgres-host
        restart: unless-stopped
        env_file:
            - .env
        environment:
            - POSTGRES_USER
            - POSTGRES_PASSWORD
            - POSTGRES_DB
            - POSTGRES_NON_ROOT_USER
            - POSTGRES_NON_ROOT_PASSWORD
        volumes:
            - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
            - db-postgres-volume:/var/lib/postgresql/data
            - db-postgres-backup-volume:/var/backups
        healthcheck:
            test: [ 'CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}' ]
            interval: 10s
            timeout: 5s
            retries: 5
        ports:
            - 5432:5432
        networks:
            - n8n-network

    n8n:
        image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
        container_name: n8n-n8n
        restart: unless-stopped
        environment:
            - N8N_HOST=n8n.mydomain.com
            - N8N_PORT=5678
            - N8N_PROTOCOL=https
            - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
            - DB_TYPE=postgresdb
            - DB_POSTGRESDB_HOST=n8n-postgres-host
            - DB_POSTGRESDB_PORT=5432
            - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
            - DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
            - DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
            - EXECUTIONS_PROCESS=main
            - N8N_RUNNERS_ENABLED=true
            - N8N_RUNNERS_MODE=external
            - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
            - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
            - N8N_NATIVE_PYTHON_RUNNER=true
            - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
            - TZ=${GENERIC_TIMEZONE}
            - N8N_BASIC_AUTH_ACTIVE=true
            - N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
            - N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
            - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
            - WEBHOOK_URL=https://n8n.mydomain.com/
            - N8N_PROXY_HOPS=1
            - NODES_EXCLUDE='["n8n-nodes-base.executeCommand","n8n-nodes-base.ssh"]'
            - EXECUTIONS_DATA_PRUNE=true
            - EXECUTIONS_DATA_SAVE_SUCCESSFUL=true
            - EXECUTIONS_MODE=queue
            - QUEUE_BULL_REDIS_HOST=n8n-redis-host
            - N8N_EXECUTIONS_CACHE_ENABLED=true
            - N8N_SCHEDULER_ENABLED=true
            # Lista de auditoria de segurança
            - N8N_LOG_LEVEL=debug
            - N8N_LOG_FILE_SIZE_MAX=50
            - N8N_LOG_FILE_COUNT_MAX=10
            # Scheduler durável
            - N8N_COMMUNITY_PACKAGES_ENABLED=true
            - N8N_USE_WORKFLOW_PUBLICATION_SERVICE=true
            #- NODE_FUNCTION_ALLOW_EXTERNAL=ioredis
            #- NODE_FUNCTION_ALLOW_BUILTIN="*"
        ports:
            - 5678:5678
        links:
            - postgres
        volumes:
            - n8n-storage-volume:/home/node/.n8n
            - n8n-file-volume:/files
        depends_on:
            postgres:
                condition: service_healthy
            redis:
                condition: service_started
        healthcheck:
            test: ["CMD", "wget", "--spider", "-q", "http://localhost:5678/healthz"]
            interval: 30s
            timeout: 10s
            retries: 3
        networks:
            - n8n-network
            - shared-network

    redis:
        image: redis:7-alpine
        container_name: n8n-redis
        hostname: n8n-redis-host
        restart: unless-stopped
        volumes:
            - redis-data-volume:/data
        networks:
            - n8n-network

    n8n-runner:
        image: n8nio/runners:${N8N_VERSION}
        container_name: n8n-n8n-runner
        restart: unless-stopped
        ports:
            - 5680:5680
        environment:
            - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
            - N8N_RUNNERS_TASK_BROKER_URI=http://n8n-n8n:5679
            - N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT=20
            - N8N_RUNNERS_LAUNCHER_LOG_LEVEL=debug
        depends_on:
            - n8n
        networks:
            - n8n-network

Configação do proxy reverso Nginx

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
server {
        #listen 80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2  on;
        server_name n8n.mydomain.com;

        ssl_certificate /var/server-auth/n8n.mydomain.com.crt;
        ssl_certificate_key /var/server-auth/n8n.mydomain.com.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 1d;

        # access_log /var/log/nginx/n8n.mydomain.com_access.log;
        error_log /var/log/nginx/n8n.mydomain.com_error.log;

        # arquivo de verificação letsencrypt
        location /.well-known/acme-challenge {
            root /var/www/letsencrypt;
        }

        client_max_body_size 50m;
        client_body_timeout 60s;

        # Cabeçalho de segurança para n8n
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        #add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss://n8n.mydomain.com; frame-ancestors 'none'" always;

        location / {
            proxy_pass    http://n8n-n8n:5678/;
            proxy_http_version 1.1;

            # Preservar cabeçalhos
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # Para SSL do Webhook n8n
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Port $server_port;
            proxy_set_header X-Original-Host $host;

            # (Opcional) passthrough de origem se seu aplicativo precisar
            proxy_set_header Origin $http_origin;

            # WebSocket (Editor n8n)
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;

            # Desabilitar buffer/cache para streaming/WS
            chunked_transfer_encoding off;
            proxy_buffering off;
            proxy_cache off;

            proxy_cache_bypass $http_upgrade;

            proxy_connect_timeout       600;
            proxy_send_timeout          600;
            proxy_read_timeout          600;
            send_timeout                600;
        }
}

Informações sobre sua configuração n8n

  • Versão n8n: 2.30.7
  • Banco de dados (padrão: SQLite): postgres:16-alpine
  • Configuração N8N EXECUTIONS_PROCESS (padrão: own, main): main
  • Executando n8n via (Docker, npm, n8n cloud, app desktop): Docker Compose
  • Sistema operacional: Ubuntu 24.04 LTS 64bit

Oi @mobabel, enquanto você aguarda uma resposta, aqui estão algumas coisas que podem ajudar:

[details=“Recursos sugeridos”]

Correspondência automática com sua pergunta.

Documentação:

Fórum:

  • [Workflows Presos em Status „Enfileirado

Seu arquivo Compose contém a causa: EXECUTIONS_MODE=queue está ativado, mas os serviços exibidos não incluem um worker de fila n8n. O n8n-runner externo é um executor de tarefas para tarefas Code/Python; ele não consome trabalhos de execução de fluxo de trabalho do Redis. O processo principal do n8n, portanto, enfileira todas as execuções de produção e elas permanecem Queued / Starting soon.

Você pode corrigir isso de duas maneiras:

  1. Para uma configuração de instância única, remova EXECUTIONS_MODE=queue (ou defina-o de volta para o modo regular padrão) e reimplante.
  2. Se você deseja o modo de fila, adicione outro serviço usando a mesma imagem n8n com command: worker. Ele deve usar o mesmo Postgres, Redis, N8N_ENCRYPTION_KEY, versão do n8n e rede Docker que o serviço principal. Confirme em seus logs que o worker está pronto e conectado ao Redis.

EXECUTIONS_PROCESS=main não cria um worker de fila, portanto não resolve isso. Após reimplantar, acione uma nova execução de produção primeiro; assim que ela começar imediatamente, repita ou limpe as execuções enfileiradas antigas conforme apropriado.

Além do acima mencionado, existem opções de env sendo definidas que não existem. Recomendo verificar sua configuração contra a documentação.

É seguro assumir que você usou uma ferramenta baseada em IA para gerar o arquivo compose que está usando?

Oi @mobabel Bem-vindo!
Se você optar pela rota do modo de fila, o contêiner do worker precisa de seu próprio sidecar de executor de tarefas. O corretor de tarefas fica dentro de cada processo n8n, então seu contêiner de executor existente está vinculado apenas à instância principal, e um worker em execução no modo externo não possui nenhum executor anexado a ele, o que deixa as tarefas do nó Code sem nada para captá-las. Forneça ao worker as mesmas variáveis de executor que você definiu na principal e, em seguida, aponte um segundo contêiner de runners para o worker:

  n8n-worker-runner:
    image: n8nio/runners:${N8N_VERSION}
    container_name: n8n-worker-runner
    environment:
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
      - N8N_RUNNERS_TASK_BROKER_URI=http://<your-worker-container-name>:5679
    depends_on:
      - n8n-worker
    networks:
      - n8n-network

OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS tem como padrão false, então a principal continua executando execuções manuais e ainda precisa do contêiner de runners que você já tem. Mantenha a imagem de runners na mesma versão que a imagem n8n.

Olá Jon,

Obrigado pelo seu feedback. Não usei ferramentas de IA para gerar o arquivo Docker Compose YAML porque não confio em IA neste caso. O N8N tem muitas versões, e as configurações yml mudam o tempo todo.

Li muitos documentos e montei meu YAML a partir de alguns códigos-fonte.

Olá Byte_Nova,

Muito obrigado pelo seu suporte rápido!

Seguindo sua resposta, encontrei a causa raiz: meu arquivo YAML estava faltando o n8n-worker.

A partir do documento oficial “Use Docker Compose | Deploy | n8n Docs”, não encontrei informações sobre o n8n-worker adicional para execuções em fila. Mas com sua dica sobre o n8n-worker, após pesquisar, encontrei este exemplo Self hosted n8n with workers, running, but Task Runners are unhealthy?

e este n8n-workers-docker/docker-compose.yml at main · davorpavlov/n8n-workers-docker · GitHub

Este é meu YAML final funcionando para n8n-worker:

    n8n-worker:
        image: n8nio/n8n:${N8N_VERSION}
        container_name: n8n-worker
        restart: always
        command: worker
        ports:
            - 5679:5678
        environment:
            - 'GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-Europe/Berlin}'
            - 'TZ=${TZ:-Europe/Berlin}'
            - DB_TYPE=postgresdb
            - DB_POSTGRESDB_HOST=n8n-postgres-host
            - DB_POSTGRESDB_PORT=5432
            - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
            - DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
            - DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
            - EXECUTIONS_MODE=queue
            - QUEUE_BULL_REDIS_HOST=redis
            - QUEUE_BULL_REDIS_PORT:6379
            - QUEUE_HEALTH_CHECK_ACTIVE=true
            #- QUEUE_BULL_REDIS_PASSWORD=""
            - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
            - N8N_RUNNERS_MODE=external
            - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
            - N8N_RUNNERS_BROKER_PORT=5679
            - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
            - 'N8N_NATIVE_PYTHON_RUNNER=${N8N_NATIVE_PYTHON_RUNNER:-true}'
            - 'N8N_RUNNERS_MAX_CONCURRENCY=${N8N_RUNNERS_MAX_CONCURRENCY:-5}'
            - 'N8N_BLOCK_ENV_ACCESS_IN_NODE=${N8N_BLOCK_ENV_ACCESS_IN_NODE:-true}'
            - 'N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-true}'
            - 'N8N_PROXY_HOPS=${N8N_PROXY_HOPS:-1}'
            #- 'N8N_GIT_NODE_DISABLE_BARE_REPOS=${N8N_GIT_NODE_DISABLE_BARE_REPOS:-true}'
            #- 'N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=${N8N_SKIP_AUTH_ON_OAUTH_CALLBACK:-false}'
            - N8N_LOG_LEVEL=${N8N_LOG_LEVEL}
        healthcheck:
            test:
                - CMD-SHELL
                - 'wget -qO- http://127.0.0.1:5678/healthz'
            interval: 5s
            timeout: 20s
            retries: 10
        depends_on:
            n8n:
                condition: service_healthy
            postgres:
                condition: service_healthy
            redis:
                condition: service_healthy
        networks:
            - n8n-network

Após reimplantação, as execuções em fila funcionam maravilhosamente.

Obrigado a todos que me ajudam por aqui! Tudo de bom!!