CI/CD sem madrugadas de deploy: o que muda com automação de verdade
Deploys na madrugada são sintoma, não destino. Veja como automação, testes confiáveis e entrega progressiva eliminam o risco do go-live.
Se a sua equipe ainda agenda deploys para a madrugada de sábado, o problema não é o horário — é a falta de confiança no processo. Quando cada release é um evento arriscado, faz sentido fazer escondido, com poucas pessoas e a esperança de que nada quebre. Automação de verdade muda isso. O objetivo deste artigo é prático: mostrar como sair do deploy-evento e chegar ao deploy não-evento, com pipeline reproduzível, testes confiáveis e entrega progressiva — usando exemplos concretos de GitLab CI/CD.
Por que o deploy vira um evento
Deploys assustam quando:
- O processo é manual e cheio de etapas que só uma pessoa conhece.
- Não há testes automatizados confiáveis cobrindo o caminho crítico.
- Reverter é difícil, então um erro vira incidente prolongado.
Cada um desses pontos tem solução, e nenhuma delas é "deployar com mais cuidado". O cuidado individual não escala: ele depende de uma pessoa específica estar acordada, lúcida e disponível. O que escala é o processo codificado, versionado e executável por qualquer pessoa do time.
Vale separar dois custos que costumam ser confundidos. O custo direto é o tempo da janela noturna e o pessoal de plantão. O custo indireto, maior, é o acúmulo: quanto mais raro o deploy, maior o lote de mudanças por release, maior a superfície de erro e mais difícil isolar a causa quando algo quebra. A madrugada não reduz risco — ela apenas esconde o sintoma de quem está dormindo.
Os três pilares de um deploy tranquilo
1. Pipeline reproduzível
Tudo que acontece entre o commit e a produção precisa estar no pipeline — versionado, automatizado e idêntico a cada execução. Nada de scripts na máquina de alguém.
Na prática, isso significa que o build, os testes e o deploy vivem no .gitlab-ci.yml (ou em arquivos incluídos via include), não em um runbook de wiki que ninguém atualiza. A mesma definição roda em merge request, em branch e em produção. Imagens de container com tag fixa garantem que o ambiente de execução não mude por baixo dos panos.
stages:
- build
- test
- deploy
build:
stage: build
image: node:20-bookworm
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
Dois detalhes que separam um pipeline frágil de um reproduzível: usar npm ci (instala exatamente o que está no lockfile) em vez de npm install, e fixar a tag da imagem base em vez de latest. Ambos eliminam a classe de bug "funciona no meu pipeline, falha no seu".
2. Testes que dão confiança
Não basta ter testes; é preciso confiar neles. Suítes de unidade, integração e API rodando em minutos transformam o "será que quebrou?" em um sinal verde objetivo.
Confiança vem de duas propriedades: a suíte é rápida o suficiente para rodar a cada commit, e é estável o suficiente para que um vermelho signifique sempre um problema real. Teste instável (flaky) é pior que teste ausente, porque treina o time a ignorar a falha. Coloque em quarentena ou conserte o teste flaky no mesmo dia — não deixe acumular.
test:unit:
stage: test
image: node:20-bookworm
script:
- npm ci
- npm run test:unit
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == "main"'
test:api:
stage: test
image: node:20-bookworm
services:
- postgres:16
variables:
DATABASE_URL: "postgres://test@postgres:5432/test"
script:
- npm ci
- npm run test:api
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
Estruture a suíte em camadas, do mais barato ao mais caro:
| Camada | O que cobre | Quando roda | Tempo-alvo |
|---|---|---|---|
| Unidade | Lógica de negócio isolada | Cada commit/MR | Segundos |
| Integração / API | Contratos com banco e serviços | Cada MR | Poucos minutos |
| End-to-end | Caminho crítico do usuário | MR de release ou nightly | Minutos a dezenas |
A regra prática: tudo que precisa estar verde antes do merge tem que caber na paciência de quem abriu o MR. Empurre o que for lento (E2E completo, carga) para execuções nightly ou para o pipeline de release.
3. Entrega progressiva
Em vez de mandar 100% do tráfego para a nova versão de uma vez, o deploy canário libera aos poucos:
10% -> observa metricas -> 50% -> observa -> 100%
(rollback automatico se latencia ou erro piorarem)
Se a nova versão degrada latência ou erro, o rollback é automático — antes que o usuário perceba.
A entrega progressiva só funciona se houver um sinal objetivo para promover ou reverter cada passo. Defina antes do deploy quais métricas observar e qual o limite de tolerância. Tipicamente: taxa de erro (5xx), latência de cauda (p95/p99) e, quando relevante, uma métrica de negócio (conversão, checkout). O canário compara a nova versão contra a estável recebendo tráfego ao mesmo tempo, o que isola variações de horário e sazonalidade.
Existem mais estratégias além do canário, com trade-offs diferentes:
| Estratégia | Como funciona | Vantagem | Custo / Trade-off |
|---|---|---|---|
| Rolling | Substitui instâncias aos poucos | Simples, sem infra extra | Rollback mais lento; versões convivem |
| Blue-green | Dois ambientes; troca o tráfego de uma vez | Rollback instantâneo | Dobra a infra durante a troca |
| Canário | Fração crescente de tráfego na nova versão | Detecta regressão com baixo blast radius | Exige boa observabilidade e automação |
No GitLab, o gate de promoção pode ser explícito enquanto o time amadurece a automação, usando ambientes e um passo manual:
deploy:canary:
stage: deploy
environment:
name: production/canary
script:
- ./deploy.sh --weight 10
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
deploy:promote:
stage: deploy
environment:
name: production
script:
- ./deploy.sh --weight 100
when: manual
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
À medida que a confiança nas métricas cresce, o when: manual da promoção dá lugar a um gate automático baseado nos limites definidos — e é aí que o "deploy na madrugada" deixa de fazer sentido.
Reverter precisa ser barato
Nenhum dos três pilares importa se reverter for caro. Trate o rollback como caminho de primeira classe, não como exceção heroica:
- Toda release é uma versão imutável e identificável (tag/digest), nunca uma sobrescrita.
- Migrações de banco são compatíveis para frente e para trás dentro de uma janela de release — adicione colunas antes, remova depois, em deploys separados.
- O rollback é o mesmo mecanismo do deploy, apontando para a versão anterior. Se reverter exige um procedimento diferente do deploy, ele não foi testado.
A pergunta de verificação é simples: se a release atual quebrar agora, em quantos minutos e com quantos comandos voltamos ao estado anterior? Se a resposta envolve "depende de quem está de plantão", o trabalho ainda não terminou.
Checklist para sair da madrugada
Use isto como um caminho incremental, não como tudo-ou-nada:
- Mova o deploy manual para um job de pipeline, mesmo que ainda com
when: manual. - Garanta que o build seja reproduzível: lockfiles, imagens com tag fixa,
npm cie equivalentes. - Estabilize a suíte de testes e bloqueie o merge em vermelho.
- Torne o rollback um job tão simples quanto o deploy e teste-o de propósito.
- Instrumente erro e latência de cauda em produção, com dashboards que o time olha.
- Introduza canário com promoção manual; defina os limites de erro/latência por escrito.
- Automatize a promoção e o rollback com base nesses limites.
- Aumente a frequência: comece com um deploy diário em horário comercial e suba a partir daí.
Cada passo reduz risco de forma isolada. Você colhe benefício antes de chegar ao fim da lista — e é exatamente por isso que dá para começar nesta sexta-feira em vez de na próxima virada de trimestre.
O efeito cultural
Quando o deploy deixa de ser arriscado, ele deixa de ser raro. Times maduros entregam várias vezes por dia, em horário comercial, sem cerimônia. A frequência alta é consequência da confiança, não da coragem.
O melhor deploy é o que ninguém percebe que aconteceu.
A automação não elimina o trabalho de engenharia — ela elimina o medo. E um time sem medo de entregar é um time que entrega mais e melhor.
Para referência de sintaxe e recursos de pipeline, consulte a documentação oficial do GitLab CI/CD.
Quer transformar seus deploys em não-eventos? Agende um diagnóstico.