Trabalhos / Deploys sem downtime
Deploys sem downtime, várias vezes por dia
Releases blue-green com Docker, GitHub Actions e nginx, usados por todos os produtos que eu lidero, com deploys várias vezes por dia.
O problema
Antes disso, alguns serviços reiniciavam no próprio servidor a cada release, então cada deploy era uma pequena queda, e o time esperava a noite para publicar.
O objetivo era simples: deploys seguros o bastante para rodar numa terça à tarde sem ninguém perceber, e uma release com problema que nunca chega aos usuários.
Como funciona um release
- Build. O GitHub Actions valida o pull request, gera a imagem Docker e envia para o servidor.
- Subir o slot livre. A versão nova sobe no slot que não está recebendo tráfego, ao lado do que está no ar.
- Health gate. O slot novo precisa passar no health check. Se não passar, nada muda e os usuários nunca veem a release com problema.
- Trocar. O nginx recarrega com o slot novo como upstream. As requisições em andamento terminam no slot antigo.
- Avisar. O resultado vai para o Discord do time.
O que não pode ser blue-green
Rodar duas versões lado a lado é a parte fácil. O trabalho de design de verdade está nas peças que nunca podem rodar duas vezes, ou que precisam funcionar com as duas versões ao mesmo tempo.
Migrations de banco
As migrations seguem expand e contract: primeiro adiciona, e só remove depois que nenhuma versão no ar depende do formato antigo. Durante a troca, o código antigo e o novo rodam sobre o mesmo schema.
Workers e rotinas agendadas
Os workers de fila e os crons rodam como instância única e não são duplicados. As filas são pausadas por um endpoint durante a troca, para nenhum job ser processado duas vezes. As rotinas financeiras ficam num worker dedicado, então existe exatamente um escritor.
Conexões com estado
O gateway de mensagens mantém conexões de longa duração que só um processo pode ter por vez, então ele nunca roda duas vezes. Reinicia de forma graciosa em vez de usar blue-green.
Trade-offAlguns segundos de reconexão nesse serviço, em troca de nunca ter dois processos disputando a mesma conexão.
Em volta do deploy
- Backups diários do PostgreSQL no S3, com versionamento, regras de retenção e credenciais de privilégio mínimo.
- Um contrato de health check único para os serviços da plataforma de IA. Um WhatsApp desconectado de um cliente nunca deixa o status da plataforma vermelho.
- Dependabot e validação de pull request em todos os repositórios principais.
Resultado
Deploy deixou de ser um evento. Os cinco serviços em produção passam pelo mesmo processo, várias vezes por dia, em horário comercial, e uma release com problema para no health gate em vez de chegar aos usuários.
A frequência de deploys vem do histórico do GitHub Actions dos cinco serviços em produção. Detalhes dos servidores não são divulgados.