O que é o Runner
O Runner é um daemon que vive no seu servidor e:
- Faz
git fetchem repos configurados (a cada N minutos, via cron) - Detecta novos commits na branch alvo (
mainpor padrão) - Faz build da imagem Docker (ou puxa imagem pronta)
- Sobe container novo, espera health check passar, reverte tráfego
- Mata container antigo (blue-green)
- Notifica resultado (Telegram, webhook)
Comparação com ferramentas que você já conhece
vs `docker run`
| docker run | runner deploy |
|---|---|
| Manual | Automatizado a cada push |
| Você escolhe a tag | Runner escolhe o commit hash |
| Sem health check ativo | Probe HTTP/TCP antes de cortar tráfego |
| Sem rollback | Volta pra versão anterior se health fail |
| Sem state file | Mantém histórico de versões |
vs GitHub Actions (`workflows/*.yml`)
GitHub Actions roda na infraestrutura do GitHub e empurra build pro seu servidor (via SSH ou registry). Runner roda no seu servidor e consome o Git. Vantagens do Runner:
- Não exige opening port 22 ou registry público
- Não consome minutos de Actions
- Estado fica visível (
runner list,runner status) - Healthcheck integrado ao pipeline
vs ArgoCD (Kubernetes)
ArgoCD opera no padrão GitOps mas exige cluster Kubernetes. Runner é GitOps para Docker plain — mesma filosofia ("desired state está no Git"), sem Kubernetes.
Quando NÃO usar o Runner
- Você precisa de multi-region failover automático → use Kubernetes
- Você quer terceirizar infra → use Render, Fly, Railway
- Sua app não tem Dockerfile e você não quer escrever um → use PaaS
Próximo passo
Instalar o Runner ou veja Quickstart 5min.
Arquitetura Interna
O Runner orquestra um pipeline de 8 etapas para garantir deploys confiáveis:
┌─────────────────────────────────────────────────────────────────┐
│ SERVIDOR PRODUCAO │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Runner CLI (/opt/runner/runner) │
│ | │
│ | Pipeline de Deploy │
│ v │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. Fetch - Detecta mudancas no Git │ │
│ │ 2. Prepare - Extrai versao, cria diretorios │ │
│ │ 3. Artifacts - Copia artefatos buildados │ │
│ │ 4. Environment - Processa .env e .secrets │ │
│ │ 5. Test - Container blue-green, health check │ │
│ │ 6. Promote - Atualiza Traefik, roteia trafego │ │
│ │ 7. Cleanup - Remove versoes antigas │ │
│ │ 8. Notify - Telegram/Discord │ │
│ └─────────────────────────────────────────────────────────┘ │
│ | │
│ v │
│ Docker + Traefik │
│ | │
│ v │
│ Aplicacao rodando │
│ │
└─────────────────────────────────────────────────────────────────┘Componentes Principais
Runner CLI: Binário Rust que orquestra o pipeline de deploy. Responsabilidades incluem gerenciar apps registradas, detectar mudanças no Git, executar o pipeline e enviar notificações.
Estado: Persistência em /opt/runner/state/ com arquivos YAML por app ({app}.yml) e configurações de PRs, staging e canary deployments.
Aplicações: Cada app registrada fica em /data/apps/{usuario}_{repo}/ com estrutura de versões (v1.0.0/, v1.0.1/, etc.) e symlink current apontando para a versão ativa.
Traefik Integration: O Runner gera configuração dinâmica em /etc/traefik/dynamic/{projeto}.yml com routers (domínio → serviço) e weighted services para canary deployments.
Fluxo de Deploy Simplificado
- Detecção (cron a cada 5min):
runner fetch --deploycompara HEAD local vs remoto - Prepare: Extrai versão, cria diretório
/data/apps/{app}/src/{instance}/{version}/ - Artifacts: Copia artefatos buildados da branch de deploy
- Environment: Processa
.env.template, gera.enve.secrets - Test: Sobe container blue-green, espera health check passar
- Promote: Atualiza symlink
currente recarrega Traefik (~5s) - Cleanup: Remove containers de versões antigas, mantém
keep_versionsmais recentes - Notify: Envia resultado (Telegram/Discord com
deploy_id)
Segurança
- Tokens GitHub transmitidos via GIT_ASKPASS, nunca em
ps aux - Secrets criptografados em
.secrets(apenas com--ckey) - Labels CCS para identificação de containers (projeto, instância, versão)
- Health check obrigatório antes de cortar tráfego
Sem Traefik (v2.0.1)
Para backends sem Traefik local: instâncias sem domain pulam geração de config, portas mapeadas diretamente com ports: no .deploy.yml.