Skip to content

ADR-004 — Estratégia de Deploy (Script + Docker Compose)

Data: 2026-03
Status: Ativo

Contexto

Precisávamos de uma estratégia de deploy que:

  • Funcione em um único servidor VPS
  • Injete secrets do Azure Key Vault no momento do build
  • Garanta que Traefik sempre receba as labels corretas
  • Seja simples de executar sem pipeline CI/CD complexo

Alternativas consideradas

AlternativaMotivo de descarte
KubernetesOver-engineering para um servidor; complexidade operacional alta
GitHub Actions + RegistryRegistry privado adiciona custo e complexidade; push de imagem para VPS continua sendo necessário
Dokku/CoolifyMenos controle sobre o processo de build; difícil injetar secrets de Key Vault
Docker SwarmSimilar ao Kubernetes em complexidade para o porte atual
Script local + Docker ComposeControle total, simples, funciona sem infra extra — escolhido

Decisão

deploy.sh — script shell que orquestra o deploy completo:

  1. Carrega AZURE_CLIENT_SECRET de /home/crm/.crm-secrets
  2. Busca CLERK_PUBLISHABLE_KEY do Key Vault via docker exec no container backend
  3. Builda imagens localmente com --no-cache e tag timestamp
  4. Atualiza .env com as novas tags de imagem
  5. Sobe containers com os 3 arquivos de compose obrigatórios
  6. Aguarda health checks
  7. Verifica que os containers rodando usam as imagens esperadas
  8. Limpa imagens dangling

3 arquivos compose obrigatórios:

  • docker-compose.yml — definição base
  • docker-compose.override.yml — configuração de produção (env, health checks, CPU)
  • docker-compose.labels.yml — labels Traefik (roteamento)

Por que o deploy.sh é obrigatório

A razão principal é a injeção de NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY no build do frontend. Esse valor:

  • Fica no Azure Key Vault (não no .env do servidor)
  • Precisa ser passado como --build-arg no docker build
  • NÃO está disponível como variável de ambiente simples

Sem o deploy.sh, o docker compose up usaria o valor vazio ou desatualizado → Clerk não funciona → sistema fora do ar.

Histórico de incidentes: Sistema derrubado 4 vezes (04-14, 04-17, 04-20 x2) por uso direto de docker compose up.

Proteção adicional

Um wrapper em /home/crm/bin/docker bloqueia chamadas diretas de docker compose up/restart/recreate nos containers crm-galdix-*. O deploy.sh usa /usr/bin/docker diretamente para contornar o wrapper.

Consequências

Positivas:

  • Deploy simples: bash deploy.sh ou bash deploy.sh backend
  • Health checks automáticos — deploy falha se o serviço não sobe
  • Verificação de imagem — garante que o container usa a imagem buildada agora
  • Limpeza automática de imagens antigas

Negativas:

  • Deploy manual — não tem CI/CD automático em push
  • Sem rollback automático (requer identificar a imagem anterior manualmente)
  • Deploy só funciona de dentro do servidor (sem deploy remoto automatizado)

Referências de implementação

  • /home/crm/app/deploy.sh
  • /home/crm/app/docker-compose.yml
  • /home/crm/app/docker-compose.override.yml
  • /home/crm/app/docker-compose.labels.yml

Ver também: Deploy, Rollback

Documentação interna — Galdix CRM