0022 — Self-deploy do central pelo próprio /api/ci/deploy¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-08-31 · Decidido em: 2026-08-31
Contexto¶
A 0021 (adoção do control-plane, ADR central
0026) fechou o deploy da frota pelo
POST /api/ci/deploy, mas recusava o deploy do próprio central (self_deploy_refused, 409) — a
"exceção de bootstrap": o central deployaria a si mesmo direto na API do Coolify a partir do seu
build-deploy.yml, sem passar pelo endpoint, "pra não depender de si mesmo no ar".
Ao migrar o central pra CI 100% GitHub (ADR central 0027, pipeline.yml), essa exceção não se
sustenta: a API /api/v1 do Coolify é restrita ao IP da casa, e o runner do GitHub tem IP
arbitrário → o build-deploy.yml não alcança a API direta; a ponte SSH que contornava isso foi
removida (0026). A cláusula "deploya direto na API" ficou inexequível.
Decisão¶
O central se deploya pelo próprio /api/ci/deploy, como qualquer app da frota. A guarda
self_deploy_refused é removida.
- O job
deploydopipeline.ymldo central fazPOST /api/ci/deploy {target, image}ao próprio central (image = fonte.xadm.biz/xadm/central-backend:<target>-amd64, a âncora de resolução — 0021), byte-idêntico ao job da frota. - O central-atual (no ar, dentro da casa) recebe o POST, resolve o próprio recurso Coolify (a
linha entra no
app_deploy_targetspelo reconcile on-boot — oDeployReconcileServicenão tem self-skip) e chama a API do Coolify localmente (IP da casa — sem o bloqueio do runner). O Coolify faz rolling deploy health-gated: a imagem nova sobe, passa no health → substitui; falha → a anterior segue no ar. - Não há auto-referência travante: o central-atual está no ar no disparo, e a chamada ao Coolify
enfileira e retorna antes do swap do container. O
imageé a âncora (0021),app_idnão resolve.
Alternativas descartadas¶
- Manter "deploya direto na API do Coolify" (0021/0026) — inexequível do runner GitHub (API IP-restrita), e a ponte SSH que a viabilizava foi removida.
- Webhook de deploy do Coolify por-alvo (secret no repo) — resolve o IP, mas adiciona um mecanismo e
secrets novos onde o
/api/ci/deployjá existe e alcança o Coolify de dentro da casa. Preterido — mais superfície por zero ganho. - Coolify auto-pull no push — menos controle do momento, sem auditoria; fica como reserva.
Consequências¶
- Reverte a guarda
self_deploy_refuseddoDeployService(ocentral.self.slugsome — era usado só nela). O caso de teste do 409 vira "self-deploy resolve e enfileira". - Break-glass: o central fora do ar não se autodeploya (não há quem receba o POST) → deploy manual pela UI/API do Coolify (de dentro da casa). É cenário de incidente, no runbook — o caminho normal (central-atual no ar) cobre todo release.
- Emenda à 0021 (a §Decisão "guarda bootstrap" e a §Consequências "self-deploy 409" ficam corrigidas
in-place apontando pra cá) e handoff feedback à ADR central 0026 (que ainda diz "sem
auto-referência" / "API direta" — as duas quebradas; a casa deve inverter: self-deploy pelo
/api/ci/deploy+ break-glass). - Sem migration nova, sem novo endpoint — só a remoção da guarda + o job
deploydopipeline.yml.