Evolution API Desconexão Redis e Erros de Iptables em Configuração YunoHost/Docker

Descreva o problema/erro/pergunta

Ambiente:

  • SO: Debian 12 (via YunoHost)

  • Configuração: Evolution API rodando no Docker junto com serviços YunoHost (n8n, etc.)

  • Infraestrutura: Auto-hospedado em um VPS

O Problema: Estou executando Evolution API via Docker Compose. Apesar de ter um serviço Redis definido em meu docker-compose.yml, os logs da API estão inundados com: [Redis] redis disconnected

Além disso, quando tento reiniciar a stack com docker compose up -d, ocasionalmente encontro este erro de rede: Failed to Setup IP tables: Unable to enable ACCEPT OUTGOING rule: (iptables: No chain/target/match by that name)

Meu Trecho Atual de docker-compose.yml:

  evolution_api:
    image: atendai/evolution-api:latest
    environment:
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_HOST=redis
      - CACHE_REDIS_PORT=6379
    depends_on:
      - redis

  redis:
    image: redis:7-alpine

O que Já Tentei:

  1. Mudar CACHE_REDIS_HOST para redis://redis:6379.

  2. Executar yunohost firewall reload.

  3. Tentar contornar o SSO nativo do YunoHost para n8n configurando-o como acesso ‘Visitor’.

Perguntas:

  1. É conhecido que o serviço Redis nativo do YunoHost ou seu gerenciamento de iptables (AFW) entrem em conflito com a rede interna do Docker?

  2. Como posso garantir que o contêiner Docker contorne as regras de firewall do YunoHost para manter uma conexão estável com seu próprio contêiner Redis?

  3. Existem regras de chain DOCKER-USER específicas que devo injetar manualmente para parar as falhas de ACCEPT OUTGOING?

Qual é a mensagem de erro (se houver)?

Informações sobre sua configuração n8n

  • Versão n8n: 2.15.1
  • Banco de dados (padrão: SQLite): padrão
  • Configuração n8n EXECUTIONS_PROCESS (padrão: own, main): padrão
  • Executando n8n via (Docker, npm, n8n cloud, aplicativo desktop): serviço systemd (YunoHost)
  • Sistema operacional: Debian 12

Veja se isso abaixo ajuda.

Este é muito provavelmente um conflito clássico entre o mecanismo de rede do Docker e o firewall do YunoHost (AFW) no Debian 12.

A causa raiz é que o YunoHost gerencia o firewall usando nftables (e anteriormente iptables), e quando recarrega ou aplica regras, frequentemente limpa as cadeias do iptables. O Docker cria suas próprias cadeias customizadas (como a cadeia DOCKER) para lidar com o roteamento de contêineres. Quando o YunoHost limpa essas cadeias, o Docker tenta adicionar regras a uma cadeia que não existe mais, resultando no erro: iptables: No chain/target/match by that name.

Porque as regras de rede estão quebradas, seu contêiner evolution_api não consegue “ver” o contêiner redis, mesmo que estejam no mesmo arquivo compose. Isso leva ao flood de redis disconnected.

Aqui está a solução passo a passo para corrigir ambos os problemas.

1. Corrija a Configuração (Evolution API)

A Evolution API espera uma URI de Conexão, não variáveis separadas de Host e Porta. Você está usando CACHE_REDIS_HOST, que a API provavelmente ignora em favor de CACHE_REDIS_URI.

Atualize sua seção de ambiente do docker-compose.yml: Remova CACHE_REDIS_HOST e CACHE_REDIS_PORT e substitua-os por CACHE_REDIS_URI.

# Mude isto:
- CACHE_REDIS_ENABLED=true
- CACHE_REDIS_HOST=redis
- CACHE_REDIS_PORT=6379

# Para isto:
- CACHE_REDIS_ENABLED=true
- CACHE_REDIS_URI=redis://redis:6379

(Nota: Se você estiver usando uma senha para o Redis, o formato é redis://:senha@redis:6379).

2. Resolva o Conflito de iptables / YunoHost

Para corrigir o erro Unable to enable ACCEPT OUTGOING rule e restaurar a conectividade entre contêineres, você deve garantir que o Docker recrie suas cadeias de rede depois que o YunoHost inicializar o firewall.

A Correção Imediata (Manual)

Execute esses comandos em ordem para limpar o conflito e forçar o Docker a reconstruir suas regras:

# 1. Recarregue o firewall do YunoHost primeiro
yunohost firewall reload

# 2. Reinicie o daemon do Docker para forçá-lo a reinjetar suas cadeias no iptables
sudo systemctl restart docker

# 3. Traga sua stack de volta
docker compose up -d

A Correção Permanente (Automação)

Como o YunoHost pode recarregar o firewall durante atualizações ou via WebUI, as regras do Docker quebrarão novamente. Para evitar isso, você pode criar uma simples substituição do systemd para garantir que o Docker reinicie sempre que o firewall mudar, ou mais simplesmente, adicionar um cron job/hook.

Porém, a forma mais estável no YunoHost é garantir que o Docker seja a última coisa a iniciar. Se você achar que isso está acontecendo frequentemente após reinicializações, execute:

sudo systemctl enable docker

E se você recarregar manualmente o firewall, sempre siga-o com sudo systemctl restart docker.

Respostas às suas questões específicas:

1. O Redis nativo do YunoHost ou o gerenciamento de iptables são conhecidos por entrar em conflito?

Sim. O gerenciamento de firewall do YunoHost é agressivo. Ele não “conhece” as cadeias customizadas do iptables do Docker. Quando o YunoHost recarrega suas regras, ele apaga a cadeia DOCKER. É por isso que você vê o erro “No chain/target/match”—o Docker está tentando se comunicar com uma cadeia que o YunoHost acabou de deletar.

2. Como posso garantir que o contêiner do Docker contorne o firewall do YunoHost?

A comunicação entre contêineres (Evolution API →→ Redis) acontece na Rede Bridge do Docker via a cadeia FORWARD. O firewall do YunoHost gerencia principalmente a cadeia INPUT (tráfego vindo do mundo exterior). Os contêineres não precisam “contornar” o firewall; eles apenas precisam que as regras gerenciadas pelo Docker existam. Reiniciar o daemon do Docker depois que o firewall está ativo é a única forma de restaurar essas regras.

3. Existem regras específicas da cadeia DOCKER-USER que devo injetar?

Não. A cadeia DOCKER-USER é para suas próprias regras customizadas (por exemplo, bloquear um IP específico de atingir sua API). O erro que você está vendo não é sobre uma regra de segurança faltando, mas uma cadeia de infraestrutura faltando. Injetar regras em DOCKER-USER não vai corrigir a falha de ACCEPT OUTGOING porque essa falha acontece no processo de configuração central do Docker.

Olá,

Obrigado pela resposta.

Tentei suas configurações do docker compose, mas não consegui fazê-las funcionar. O erro “Redis disconnected” continua aparecendo. Aqui está meu arquivo docker-compose.yml mais recente:

version: '3.8'

services:
  evolution_api:
    image: atendai/evolution-api:latest
    container_name: evolution_api
    restart: always
    network_mode: "host"
    ports:
      - "8080:8080"
    environment:
      - SERVER_TYPE=http
      - SERVER_PORT=8080
      - SERVER_URL=http://my-server-ip:8080
      - CORS_ORIGIN=*
      - CORS_METHODS=GET,POST,PUT,DELETE,PATCH
      - AUTHENTICATION_TYPE=apikey
      - WA_PHONE_VERSION=2.3000.10125062854
      - CONFIG_SESSION_PHONE_CLIENT=Chrome
      - AUTHENTICATION_API_KEY=my-auth-api-key

      # Conectando ao banco de dados YunoHost
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://evolution:password@localhost:5432/evolution?schema=public

      # Conectando ao Redis do YunoHost
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_URI=redis://redis:6379

Além disso, tenho mais uma pergunta: você acha que sabe por que o código QR não aparece? Quando analisei as requisições no meu navegador não havia nada errado. Tudo parecia estar com 200 OK. Obrigado.

O motivo de você ainda estar vendo “Redis disconnected” é devido a uma incompatibilidade de rede em seu novo docker-compose.yml.

O Problema: network_mode: "host" vs. redis://redis

Você mudou para network_mode: "host". Neste modo, o container não possui sua própria rede Docker interna; ele compartilha a rede de seu VPS diretamente.

  • Como funciona agora: Dentro de seu container, localhost é o mesmo que o VPS localhost.

  • O Erro: Você disse à API para procurar Redis no hostname redis (redis://redis:6379). Porém, como você não está usando uma rede bridge do Docker, não existe entrada DNS para “redis”. O container está procurando uma máquina chamada “redis” em sua rede e não consegue encontrá-la.

Como você está tentando se conectar ao Redis nativo do YunoHost (que está executando diretamente no SO do host), você deve referir-se a ele como localhost.

O Problema: network_mode: "host" vs. redis://redis

Você mudou para network_mode: "host". Neste modo, o container não possui sua própria rede Docker interna; ele compartilha a rede de seu VPS diretamente.

  • Como funciona agora: Dentro de seu container, localhost é o mesmo que o VPS localhost.

  • O Erro: Você disse à API para procurar Redis no hostname redis (redis://redis:6379). Porém, como você não está usando uma rede bridge do Docker, não existe entrada DNS para “redis”. O container está procurando uma máquina chamada “redis” em sua rede e não consegue encontrá-la.

Como você está tentando se conectar ao Redis nativo do YunoHost (que está executando diretamente no SO do host), você deve referir-se a ele como localhost.

A Solução: docker-compose.yml Atualizado

Mude sua CACHE_REDIS_URI para usar localhost.

services:
  evolution_api:
    image: atendai/evolution-api:latest
    container_name: evolution_api
    restart: always
    network_mode: "host" 
    # Nota: 'ports' é ignorado ao usar network_mode: host, 
    # a aplicação se vinculará automaticamente à porta 8080 no IP do seu VPS.
    environment:
      - SERVER_TYPE=http
      - SERVER_PORT=8080
      - SERVER_URL=http://my-server-ip:8080
      - CORS_ORIGIN=*
      - CORS_METHODS=GET,POST,PUT,DELETE,PATCH
      - AUTHENTICATION_TYPE=apikey
      - WA_PHONE_VERSION=2.3000.10125062854
      - CONFIG_SESSION_PHONE_CLIENT=Chrome
      - AUTHENTICATION_API_KEY=my-auth-api-key

      # Conectando ao banco de dados do YunoHost (Correto)
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://evolution:password@localhost:5432/evolution?schema=public

      # Conectando ao Redis do YunoHost (CORRIGIDO)
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_URI=redis://localhost:6379 

Passo Importante: Após salvar o arquivo, execute:

docker compose up -d

Por que o código QR não está aparecendo

Você mencionou que as requisições do navegador retornam 200 OK, mas nenhum código QR aparece. Isso é diretamente causado pela desconexão do Redis.

Aqui está o motivo técnico:

  1. A Requisição (200 OK): Quando você solicita o código QR, o servidor da API está em execução, então ele aceita a requisição e retorna uma resposta HTTP válida. O “200 OK” apenas significa “O servidor está vivo e o ouviu.”

  2. O Processo (Falha): Para gerar um código QR, a Evolution API deve inicializar uma sessão do WhatsApp usando a biblioteca Baileys. Esta biblioteca precisa armazenar o estado da sessão e dados de conexão temporários.

  3. O Crash: A Evolution API usa Redis para gerenciar este estado. Como Redis está desconectado, a API falha ao criar a sessão em segundo plano. Ela retorna uma resposta de sucesso ao navegador, mas o payload (os dados reais do código QR) está vazio ou inválido porque o processo de backend falhou ao tentar escrever no Redis.

Uma vez que você corrija a CACHE_REDIS_URI para localhost e os logs de “Redis disconnected” cessarem, o código QR aparecerá imediatamente.

Dica Final para Usuários de YunoHost

Se você ainda vir “Redis disconnected” mesmo após mudar para localhost, significa que o Redis do YunoHost está configurado para permitir conexões apenas de usuários específicos ou possui uma senha.

Verifique se o Redis do YunoHost possui uma senha executando isto no terminal do seu VPS:

redis-cli ping

  • Se retornar PONG, está aberto.

  • Se retornar (error) NOAUTH Authentication required, você deve adicionar a senha à sua URI: redis://:suasenha@localhost:6379.

Obrigado pela resposta.

Já resolvi ambos os problemas com Redis e exibição de QR code.

Com relação ao primeiro problema com Redis, sua solução funcionou para mim. Fazer as alterações que você indicou no arquivo compose foi suficiente, e também reiniciei o firewall YunoHost (AFW) e o Docker.

Para o segundo problema, descobri que a imagem Evolution API não é mais suportada devido a protocolos antigos do WhatsApp. Troquei a imagem e funcionou imediatamente, sem nem precisar alterar meu arquivo compose. Compartilhei minhas configurações abaixo:

version: '3.8'

services:
  evolution_api:
    image: evoapicloud/evolution-api:latest # Essa é a estável
    container_name: evolution_api
    restart: always
    network_mode: "host"

    environment:
      - SERVER_TYPE=http
      - SERVER_PORT=8080
      - SERVER_URL=http://seu-ip-servidor:8080
      - CORS_ORIGIN=*
      - CORS_METHODS=GET,POST,PUT,DELETE,PATCH
      - AUTHENTICATION_TYPE=apikey
      - AUTHENTICATION_API_KEY=sua-chave-api
      # Mencionando separadamente versão do telefone WhatsApp e navegador.
      - WA_PHONE_VERSION=2.3000.1030415680
      - CONFIG_SESSION_PHONE_CLIENT=Chrome

      # Vamos usar o banco de dados do YunoHost.
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://evolution:password@localhost:5432/evolution?schema=public
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_URI=redis://localhost:6379

      # Opcional: configurações para estabilidade extra.
      - DELAY_MESSAGE=1000
      - QR_CODE_EXPIRATION=600

    volumes:
      - ./evolution_instances:/evolution/instances

Mesmo após resolver esses, ainda há um problema: configurei o nó trigger Evolution API, mas quando o n8n recebe uma resposta, fica preso em “Carregando dados”. Porém, não há nada de errado ao executar nós normais. Isso ocorre apenas ao executar o nó trigger. Já abri uma issue no GitHub para isso, mas ainda não encontrei nenhum recurso para corrigir. Você tem alguma informação sobre isso? Obrigado.

É ótimo ouvir que os problemas com Redis e código QR foram resolvidos! Mudar para a imagem evoapicloud foi a decisão certa—as imagens atendai estão de fato desatualizadas e frequentemente falham com os protocolos atuais do WhatsApp Web.

Com relação ao nó de acionamento do n8n ficando preso em “Carregando dados,” este é um ponto crítico conhecido ao executar n8n e Evolution API no mesmo servidor YunoHost.

Já que seus nós normais funcionam, a “tubulação” (API —> n8n) está funcionando para requisições. No entanto, um Nó de Acionamento funciona ao contrário: a API envia um Webhook para o n8n. Quando o n8n está em modo “Listen” e diz “Carregando dados,” ele está aguardando uma requisição HTTP válida atingir seu endpoint webhook.

Aqui estão os três motivos mais prováveis para isso estar acontecendo em sua configuração específica do YunoHost:

1. O Problema de Rede “Hairpin” (Mais Provável)

Você provavelmente está usando a URL Pública da sua instância n8n (por exemplo, https://n8n.seudominio.com/webhook/…) nas configurações de webhook da Evolution API.

O Problema: Quando a Evolution API (no mesmo servidor) tenta enviar dados para sua URL pública, a requisição sai para o IP do seu VPS e tenta voltar para dentro. Muitos firewalls (incluindo AFW/iptables do YunoHost) e alguns provedores de VPS bloqueiam esse “loopback” (Hairpin NAT) por razões de segurança. A requisição nunca chega ao n8n, então o nó fica em “Carregando dados” para sempre.

A Solução: Na configuração de webhook da Evolution API, tente usar o endereço interno do n8n em vez do público.

  • Mude de: https://n8n.seudominio.com/webhook/...

  • Para: http://localhost:5678/webhook/... (ou qualquer porta que seu n8n esteja rodando internamente).

2. Variável de Ambiente WEBHOOK_URL do n8n

Se o n8n não conhecer sua própria URL pública, às vezes pode gerar URLs de webhook “Test” que usam localhost ou um IP interno, que a Evolution API pode não conseguir rotear corretamente dependendo de como a rede Docker está interagindo com o serviço systemd do YunoHost.

A Solução: Certifique-se de que seu serviço n8n (via YunoHost ou variáveis de ambiente) tenha o WEBHOOK_URL definido explicitamente:

WEBHOOK_URL=https://n8n.seudominio.com/

Se isso não estiver definido, o n8n pode estar dando à API uma URL que parece correta na interface, mas que é funcionalmente quebrada para a requisição de entrada.

3. Incompatibilidade de Estrutura de Dados (O “Travamento da Interface”)

Já que você mudou para a imagem evoapicloud, a estrutura JSON dos eventos sendo enviados ao n8n pode ter mudado ligeiramente em comparação com o que o nó Evolution API do n8n espera.

Quando o nó de acionamento do n8n recebe uma requisição que não consegue analisar no esquema esperado, a interface às vezes trava em “Carregando dados” em vez de mostrar um erro porque está preso em um loop tentando mapear o JSON de entrada para os campos internos do nó.

Como testar isso:

  1. Crie um Nó de Webhook padrão no n8n (não o nó de acionamento Evolution API).

  2. Copie essa URL de Webhook e coloque-a nas configurações de webhook da Evolution API.

  3. Dispare um evento (envie uma mensagem para o bot).

  4. Se o nó de Webhook padrão receber os dados, então o problema é uma incompatibilidade de esquema no nó de acionamento Evolution API. Neste caso, você pode realmente construir seu fluxo de trabalho inteiro usando o nó de Webhook padrão e um nó “Set” ou “Code” para limpar os dados—isso é frequentemente mais estável do que usar o nó de acionamento dedicado.

Checklist de Resumo para você:

  1. Teste com um nó de Webhook padrão. Se isso funcionar, o problema é o código do Nó de Acionamento (incompatibilidade de esquema).

  2. Mude a URL do Webhook na Evolution API para http://localhost:5678/... para contornar o problema do firewall/loopback do YunoHost.

  3. Verifique os logs do n8n (sudo journalctl -u n8n ou similar) enquanto o nó está “Carregando dados” para ver se aparecem erros 403 Forbidden ou Connection Refused.

Magicamente, resolvi o problema atualizando o n8n da versão 1.15.1 para 1.19.2, embora eu não entenda realmente como foi resolvido.