Infraestrutura e Traefik

Última atualização: 20/08/2026

Variantes de orquestração

Arquivo

Uso

docker-compose.yml

Fonte de verdade — dev local e produção (host único)

docker-compose.prod-test.yaml

Bancada de teste de configuração antes de ir para produção

docker-compose.swarm.yaml

Orquestração multi-nó (não usada atualmente)

Ver ADR 0001 (docs/decisions/0001-docker-compose-vs-swarm.md, também no site de Desenvolvimento → Decisões) para o raciocínio completo.

Padrão de labels Traefik

Todos os serviços HTTP seguem o modelo em docs/modelo trafik yaml/docker-compose.yaml:

labels:
  - 'traefik.enable=true'
  - 'traefik.http.routers.${PROJECT_NAME}.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)'
  - 'traefik.http.routers.${PROJECT_NAME}.tls=true'
  - 'traefik.http.routers.${PROJECT_NAME}.entrypoints=websecure'
  - 'traefik.http.routers.${PROJECT_NAME}.tls.certresolver=lets-encrypt'
  - 'traefik.http.middlewares.${PROJECT_NAME}.headers.SSLRedirect=true'
  # ... demais headers de segurança (STS, XSS, nosniff)
  - 'traefik.http.routers.${PROJECT_NAME}.middlewares=${PROJECT_NAME}@docker'

Pontos importantes deste padrão:

  • certresolver é lets-encrypt (com hífen) — o nome do resolver configurado no Traefik do host. Um erro comum é usar letsencrypt (sem hífen), o que causa fallback silencioso para o certificado default self-signed do Traefik (ver Divergências conhecidas).

  • Serviços que não servem HTTP (workers de fila) devem ter traefik.enable=false explícito — sem isso, o provider Docker do Traefik expõe o container por padrão (exposedByDefault), criando um router implícito Host(<container_name>) (ver runbook de correção).

  • Healthchecks em imagens Alpine devem usar wget (não curl, ausente em várias imagens publicadas) e 127.0.0.1 explícito em vez de localhost (musl resolve localhost para ::1/IPv6 antes de IPv4, e a maioria dos serviços só escuta em 0.0.0.0).

Roteamento da API (evocrm-api.vya.digital)

O domínio da API é compartilhado entre evo-auth, evo-crm, evo-core e evo-processor, roteado por prioridade de PathPrefix/PathRegexp — rotas mais específicas (ex.: /api/v1/accounts/:id, webhooks com accountId) recebem prioridade maior que os catch-alls genéricos de cada serviço. O evo-crm tem o catch-all absoluto (PathPrefix('/'), prioridade 1).

Rede

Todos os serviços — incluindo os workers Sidekiq — devem estar na rede app-network (externa, pré-existente no host) para resolver hostnames internos como redis.vyadigital. Serviços fora dessa rede não conseguem resolver dependências internas mesmo estando “up”.