Canary Deployment

Canary deployment permite liberar novas versoes gradualmente, controlando a porcentagem de trafego.

Conceito

       100% trafego
           |
     +-----+-----+
     |           |
   90% v1.0.0  10% v1.1.0-rc1   <- Canary inicial
     |           |
   50% v1.0.0  50% v1.1.0-rc1   <- Aumentando
     |           |
     +-----+-----+
           |
     100% v1.1.0               <- Promoted

Quando Usar

  • Mudancas arriscadas
  • Novas features grandes
  • Mudancas de infraestrutura
  • Qualquer deploy que precise validacao em producao

Fluxo Completo

1. Deploy da Versao Canary

# Deploy normal (sera a versao canary)
runner deploy meu-app --version v1.1.0-rc1

Neste ponto:

  • Ambas as versoes estao rodando
  • v1.0.0 tem 100% do trafego
  • v1.1.0-rc1 tem 0%

2. Iniciar com 10%

runner weight meu-app production v1.1.0-rc1 10

Distribuicao:

  • v1.0.0: 90%
  • v1.1.0-rc1: 10%

3. Monitorar

Aguarde e monitore:

  • Logs de erro
  • Metricas de performance
  • Feedback de usuarios
  • Health checks
# Ver distribuicao atual
runner weights meu-app -i production

# Ver logs
docker logs meu-app_production_v1.1.0-rc1 --tail 100

4. Aumentar para 50%

Se tudo estiver bem:

runner weight meu-app production v1.1.0-rc1 50

5. Monitorar Novamente

Com 50% do trafego, problemas ficam mais evidentes. Aguarde tempo suficiente para validar.

6. Promover para 100%

Se tudo estiver OK:

runner promote meu-app -i production v1.1.0-rc1

Este comando:

  1. Define 100% do trafego para v1.1.0-rc1
  2. Remove v1.0.0 do routing
  3. Limpa container antigo (opcional)

Rollback do Canary

Se algo der errado em qualquer etapa:

Opcao 1: Reduzir Peso

# Voltar para 0%
runner weight meu-app production v1.1.0-rc1 0

Opcao 2: Destruir Versao

# Remove completamente a versao canary
runner destroy meu-app -i production --version v1.1.0-rc1

Como Funciona

O Runner usa Traefik weighted services:

# /etc/traefik/dynamic/meu-app.yml (gerado automaticamente)
http:
  services:
    meu-app-production:
      weighted:
        services:
          - name: meu-app-production-v1-0-0
            weight: 90
          - name: meu-app-production-v1-1-0-rc1
            weight: 10

Quando voce ajusta o peso, o Runner:

  1. Atualiza o arquivo YAML
  2. Traefik faz hot-reload (~5s)
  3. Trafego e redistribuido

Zero downtime: Nenhum container e reiniciado.

Exemplo Completo

# Estado inicial
$ runner versions meu-app -i production
Versoes de meu-app (production):
  v1.0.0 (current, 100%)

# Deploy canary
$ runner deploy meu-app --version v1.1.0-rc1
Deploy concluido: v1.1.0-rc1

# Iniciar canary
$ runner weight meu-app production v1.1.0-rc1 10
Peso atualizado:
  v1.0.0: 90%
  v1.1.0-rc1: 10%

# Apos monitoramento
$ runner weight meu-app production v1.1.0-rc1 50
Peso atualizado:
  v1.0.0: 50%
  v1.1.0-rc1: 50%

# Promover
$ runner promote meu-app -i production v1.1.0-rc1
Versao v1.1.0-rc1 promovida para 100%

# Estado final
$ runner versions meu-app -i production
Versoes de meu-app (production):
  v1.1.0-rc1 (current, 100%)
  v1.0.0

Boas Praticas

Nomenclatura de Versao

Use sufixos para indicar canary:

  • v1.1.0-rc1 - Release candidate 1
  • v1.1.0-rc2 - Release candidate 2
  • v1.1.0 - Versao final

Tempo de Monitoramento

  • 10% → 50%: Minimo 15 minutos
  • 50% → 100%: Minimo 1 hora
  • Producao critica: 24 horas em cada etapa

Metricas a Observar

  • Taxa de erro (deveria permanecer igual)
  • Latencia (nao deveria aumentar)
  • CPU/Memoria (verificar consumo)
  • Logs de erro (novos erros)

Criterios de Rollback

Faca rollback se:

  • Taxa de erro aumentar
  • Latencia aumentar significativamente
  • Usuarios reportarem problemas
  • Health checks falharem

Automacao

Para canary automatico, crie um script:

#!/bin/bash
# canary.sh

VERSION=$1
STEPS=(10 30 50 70 100)

runner deploy meu-app --version $VERSION

for weight in "${STEPS[@]}"; do
    echo "Setando peso para $weight%"
    runner weight meu-app production $VERSION $weight

    if [ $weight -lt 100 ]; then
        echo "Aguardando 30 minutos..."
        sleep 1800

        # Verificar health
        if ! runner health --app /apps/meu-app; then
            echo "Health check falhou, rollback!"
            runner weight meu-app production $VERSION 0
            exit 1
        fi
    fi
done

echo "Promovendo para 100%"
runner promote meu-app -i production $VERSION
By Borlot.com.br on 12/02/2026