Atualizar o WAHA
Onde a versão do WAHA é fixada, o que o nosso código assume dele e o roteiro para trocar a imagem sem derrubar os pareamentos.
A pesquisa (AD-002) é clara: biblioteca sempre atualizada é prática anti-ban, e o WAHA solta versões todo mês. Ao mesmo tempo, o payload varia por engine e por versão. Por isso a imagem é fixada por tag e cada troca passa por um roteiro.
Onde a tag mora
A imagem é sempre devlikeapro/waha, com a tag vinda de WAHA_IMAGE_TAG:
| Arquivo | Linha | Comportamento |
|---|---|---|
backend/docker-compose.yml (dev) | image: devlikeapro/waha:${WAHA_IMAGE_TAG:-latest} | sem valor usa latest, que é só amd64; no Apple Silicon use arm |
backend/docker-compose.prod.yml | image: devlikeapro/waha:${WAHA_IMAGE_TAG:?waha image tag} | sem valor o deploy falha nomeando a variável |
Em produção a tag é de engine + versão (o comentário do compose dá o exemplo
gows-2026.8.2) e nunca latest. O valor fica no ambiente do compose no
Dokploy, junto com os outros segredos (AD-012). .env.example só traz o valor
de dev (arm), e o comentário lembra que a variável é lida apenas pelo compose.
O que não se perde numa troca
- As sessões ficam no Postgres do WAHA (
waha-db, volumewahadata), não no disco do container. Trocar a imagem não desvincula ninguém. WHATSAPP_RESTART_ALL_SESSIONS: "true"reabre todas as sessões do banco no boot.- Enquanto o WAHA está fora, os webhooks não chegam; ao voltar, cada sessão manda
session.statusde novo e a máquina de estados aplica (ver WAHA fora do ar).
O que o nosso código assume do WAHA
O adapter diz ter sido conferido contra o WAHA 2026.8.2. Numa versão nova, estes são os pontos que quebram em silêncio:
| Superfície | Onde |
|---|---|
POST /api/sessions com config.proxy, config.webhooks[] (hmac.key, retries), config.metadata, config.gows.storage | waha-adapter.ts start |
GET /api/sessions/{name}, …/start, …/restart, …/logout, DELETE /api/sessions/{name} | waha-adapter.ts |
GET /api/{session}/auth/qr, POST /api/{session}/auth/request-code, GET …/auth/passkey/confirmation, POST …/auth/passkey/confirm | waha-adapter.ts challenge, confirmChallenge |
GET /api/contacts/profile-picture | waha-adapter.ts avatar |
GET /api/{session}/chats/overview, GET /api/{session}/chats/{chat}/messages | ingest/channels/whatsapp/waha-ingest.ts |
Status STOPPED, STARTING, SCAN_QR_CODE, PASSKEY_REQUIRED, PASSKEY_CONFIRMATION_REQUIRED, WORKING, FAILED | stateOf |
Envelope { id, event, session, me, payload } e header X-Webhook-Hmac (HMAC-SHA512) | waha-webhook.ts, apps/gateway/main.ts |
me.id no formato <dígitos>@c.us | identityOf |
Variáveis WAHA_GOWS_DEVICE_HISTORY_SYNC_*, WAHA_MEDIA_STORAGE, WHATSAPP_FILES_LIFETIME | os dois compose |
| Lista de senhas fracas do dashboard/Swagger | problems/2026-09-11-waha-dashboard-loop-basic-auth |
bun run ci não cobre o WAHA: os testes usam o FakeAdapter. Uma versão
nova só é validada rodando contra o container real.
Roteiro de atualização
-
Leia as notas da versão nova do WAHA procurando mudanças na engine GOWS, nos endpoints e nos status da tabela acima.
-
Local: troque
WAHA_IMAGE_TAGno.enve suba só o WAHA.backend/ docker compose pull waha docker compose up -d waha docker compose ps waha # healthy = /health respondeu com a X-Api-Key curl -fsS -H "X-Api-Key: <WAHA_API_KEY>" http://localhost:3001/health -
Com
bun run gatewayebun run workersde pé, repita o smoke que validou a integração: sessão → webhook → gateway → workers → desafio → QR por SSE → desvincular.bun run pair:qr -- <seat-uid>grava o QR do pareamento aberto. -
Confira nos logs do gateway que não há
waha webhook refused(assinatura) e, nos workers, queprovider event failed; left pendingnão aparece. -
Se possível, pareie um celular de teste e deixe a sincronização de histórico rodar: é onde as variáveis
WAHA_GOWS_DEVICE_HISTORY_SYNC_*aparecem. -
Homologação: troque
WAHA_IMAGE_TAGno ambiente do compose no Dokploy e faça o redeploy. Acompanhe a saúde: contagem depairingsDegradedno overview e a tela Conexões. -
Anote a tag anterior para voltar se algo quebrar.
Em aberto
Não existe um ambiente de homologação separado. O ambiente do Dokploy em
api.superdinda.com é o próprio "em homologação" (sem família real até
2026-10-18). Quando houver famílias reais, uma pilha de staging separada (com
o próprio waha-db) precisa existir antes desta troca.
Em aberto
Não está documentado se o WAHA migra o schema do waha-db numa troca de
versão, nem se voltar para a tag anterior é seguro depois disso. Faça backup
do volume wahadata antes de trocar em produção.
Não misturar com mudança de histórico
WAHA_HISTORY_DAYS e WAHA_HISTORY_MESSAGES_PER_CHAT são lidos pelo container
no momento do vínculo e valem para todas as sessões: mudar qualquer um significa
parear todos os celulares de novo. Não aproveite uma atualização de imagem
para mexer neles. Ver Anti-ban.
Fontes
backend/docker-compose.yml,backend/docker-compose.prod.yml,backend/.env.examplebackend/src/domains/channels/adapters/waha-adapter.ts,backend/src/domains/channels/webhooks/waha-webhook.ts,backend/src/domains/ingest/channels/whatsapp/waha-ingest.tsbackend/apps/gateway/main.ts,backend/apps/workers/consume-provider-events.ts,backend/package.json- Lane doc
k-pairing-api.md(tag fixada viaWAHA_IMAGE_TAG) - Vault: AD-002, AD-012 (deploy Dokploy),
research/2026-09-11-whatsapp-nao-oficial,problems/2026-09-11-waha-dashboard-loop-basic-auth,_state(smoke com WAHA real, "em homologação"),specs/2026-10-18-redesign-blueprint
Proxies
De qual endereço cada sessão do WhatsApp sai — proxies ISP brasileiros de IP fixo, poucos por IP, comprados pela API do IPRoyal e controlados pelo backoffice.
Anti-ban
As práticas que reduzem o risco de o WhatsApp restringir o número de uma pessoa protegida — o que a pesquisa recomenda e o que o código já impõe.
