GitOps mode — fetch automático e retry
O Runner opera em modo GitOps: um cron compara o SHA do repositório com o último deploy bem-sucedido. Se mudou, deploya. Esta página explica o mecanismo completo, o comportamento de retry e como proteger apps durante manutenção.
Pré-requisitos
- Runner instalado e configurado (
runner init) - Pelo menos uma app registrada (
runner add) - Acesso ao crontab do servidor (para configurar o cron)
Como configurar o cron
Adicione ao crontab do servidor (crontab -e):
*/5 * * * * /usr/local/bin/runner fetch --deploy >> /opt/runner/logs/cron.log 2>&1O intervalo padrão é 5 minutos. Ajuste conforme a frequência de deploys esperada — intervalos menores aumentam a carga na API do GitHub.
Como o fetch --deploy funciona
A cada execução, o runner percorre todas as apps registradas em apps_path:
Para cada app:
1. git ls-remote → lê o SHA atual do repo (branch dist)
2. Compara com state.last_deployed_commit
3. Se mudou → executa runner deploy <app>
4. Se o container morreu (mesmo SHA) → executa runner deploy <app>
5. Se status=paused → skipa sem tentarO estado de cada app fica em /opt/runner/state/<app>.yml.
Retry-exhausted — o que acontece com commits quebrados
Quando um deploy falha (healthcheck não passa, build quebra), o runner não tenta indefinidamente o mesmo commit. O controle é feito por dois campos no estado:
| Campo no state | Tipo | Função |
|---|---|---|
last_failed_commit |
string | SHA do último commit que falhou |
deploy_retry_count |
integer | Quantas vezes tentou esse SHA |
O threshold é configurado em /opt/runner/config.yml:
max_deploy_retries: 3 # default; 0 = ilimitadoApós 3 falhas no mesmo SHA, o runner para de tentar aquele commit. Quando um novo commit chega (push novo no repo), o contador zera e o ciclo recomeça.
Para ver o estado atual de uma app:
runner status minha-appAuto-pause — N falhas consecutivas no fetch (v2.23.19)
Diferente do retry-exhausted (que rastreia falhas de deploy de um SHA específico), o auto-pause rastreia falhas consecutivas no próprio fetch — quando o runner não consegue nem ler o repo remoto.
# /opt/runner/config.yml
max_consecutive_fetch_errors: 10 # default; 0 = desabilitaQuando consecutive_fetch_errors >= max_consecutive_fetch_errors, o runner muda status para paused e o cron skipa a app. Isso evita flood de erros quando o repo foi removido ou a rede está instável.
Para recuperar:
# Após corrigir o problema upstream
runner unpause minha-appVer mais em pause e unpause.
O que pode dar errado
Commit quebrado passa no healthcheck
O cenário mais crítico: o código faz git push com um bug, o container sobe, o healthcheck passa (endpoint /health sempre retorna 200), e o deploy mal-sucedido vai para produção.
Mitigação: Configure o healthcheck para um endpoint que valida dependências reais da aplicação — conexão ao banco, fila disponível, etc. Endpoint que só retorna {"status": "ok"} sem checar nada é inútil para esse propósito.
# .deploy.yml — healthcheck robusto
healthcheck:
path: /health/ready # endpoint que verifica DB, cache, etc.
interval: 10s
retries: 5Cron tenta loop infinito em build quebrado
Sem max_deploy_retries, um Dockerfile com erro de compilação tentaria um novo deploy a cada 5 minutos.
Mitigação: Manter max_deploy_retries: 3 (default). O runner para após 3 falhas no mesmo SHA e aguarda novo push.
Deploy automático durante manutenção planejada
Um push acidental ou automatizado (dependabot, CI) pode acionar deploy durante uma migração de banco em andamento.
Mitigação: Pausar a app antes de iniciar a manutenção.
runner pause minha-app
# ... executa a manutenção ...
runner unpause minha-appGitHub API rate limit
O git ls-remote consome tokens da API do GitHub. Servidores com muitas apps podem atingir o limite com intervalos curtos.
Mitigação: Usar */10 * * * * (10 minutos) para servidores com mais de 30 apps, ou configurar autenticação com token que tem limite maior.
Canary para mudanças sensíveis
Para mudanças de alto risco, use canary deployment ao invés de confiar só no healthcheck:
# .deploy.yml
instances:
production:
domain: app.meu-dominio.com
canary:
weight: 10 # começa em 10% do tráfegoCom canary ativo, o cron incrementa o peso automaticamente a cada tick configurado. Se o healthcheck falhar em qualquer ponto, o runner faz rollback automático.
Ver canary deployment.
Notificações de falha
Configure notificações para receber alertas quando um deploy falha:
# /opt/runner/config.yml
notify:
channel: telegram
telegram_bot_token: "123456:ABC..."
telegram_chat_id: "-1001234567890"
verbose_errors: true # segunda mensagem com erro completoCom verbose_errors: true, o runner envia duas mensagens: o resumo e o log completo do erro (truncado em 800 caracteres).
Links relacionados
- Pause e unpause — controle manual e auto-pause
- Status, logs e health — observabilidade
- runner fetch — referência completa do comando
- Retry-exhausted — recuperar após falhas repetidas (em breve)