Files
VPS 4 Builder 9b29f70bb0 deploy: atualiza modelo (registry VPN, poda) + delta de deploy prod do motor
- deploy/modelo.md: reescrito. Agora vale para scoreodonto E newwhats
  (padronizados). Documenta o registry PELA VPN (10.99.0.3:3000 — o proxy HTTPS
  corta uploads >~45MB em ~60s), o promote via API v2 (buildx não fala HTTP) e a
  poda de imagens no deploy-prod.sh. Versão anterior em desuso/ (17/jun).
- projetos/newwhats.clube67.com/deploy-prod.md: novo delta do motor — host único,
  build com contexto na raiz (plugins na imagem), banco newwhats_prod + Dragonfly /2
  na VPS3, rede soc, JWT do dev, sem migração Prisma no boot, auth do promote pelo
  docker login do runner, e o sync-config-dev-para-prod.sh como passo separado.

O HMR/dev já estava coberto (infra/ambiente-dev.md + delta do scoreodonto); o dev
do motor (next start + rsync, NÃO-HMR) já está em ambiente-dev.md do projeto.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 04:00:08 +02:00

3.1 KiB

Deploy — Modelo (Build Once → Promote → Deploy)

Situação: como o deploy funciona, em conceito. Estado real verificado em 11/jul/2026. Vale para scoreodonto.com E newwhats.clube67.com (padronizados no mesmo modelo).

Push na main builda uma vez e publica a imagem por commit; a tag vX.Y.Z re-tagueia essa mesma imagem (sem rebuild) e deploya. Produção nunca builda — só executa imagens prontas.

 PUSH main (commit C)                 TAG vX.Y.Z (no commit C)
        │                                     │
        ▼                                     ▼
   CI: build (1x)                       CI: promote (SEM build)
   publica :C + :latest                 copia manifest :C → :vX.Y.Z (MESMO digest) + deploy
        ▼                                     ▼
   registry (Gitea, pela VPN)           produção (VPS1): pull :vX.Y.Z + up --no-build + poda

Garantia central: a imagem em produção é byte-idêntica à que foi buildada e testada. A tag é só um rótulo de release sobre um artefato imutável. O promote confere que o digest de :vX.Y.Z é igual ao de :C antes de deployar.

Registry pela VPN (10.99.0.3:3000) — importante

As imagens são publicadas e puxadas pelo endereço 10.99.0.3:3000 (WireGuard), não por git.clube67.com. Motivo: o proxy HTTPS público corta uploads em ~60 s (banda ~0,75 MB/s), então blobs acima de ~45 MB não sobem (o Gitea recebe o corpo truncado e responde 500). Pela VPN não há corte (~2,4 MB/s). O blob do backend do motor tem 175 MB — só passa pela VPN.

  • Exige insecure-registries: ["10.99.0.3:3000"] no daemon Docker do runner (VPS4) e da VPS1. A porta 3000 não é exposta na internet, só pelo túnel — insecure aqui só desliga a exigência de TLS naquele endereço; o tráfego segue cifrado pelo WireGuard.
  • O promote copia o manifest pela API v2 do registry (GET+PUT, byte a byte ⇒ mesmo digest). Não usa docker buildx imagetools, que não fala com registry HTTP.
  • Correção definitiva (pendente, não bloqueia): aumentar os timeouts do proxy da VPS3 (client_body_timeout/proxy_send_timeout/proxy_read_timeout ≥ 900s, client_max_body_size 0) resolveria também clones/downloads externos.

Poda de imagens no deploy

O deploy-prod.sh, ao fim de cada deploy, remove as imagens vX.Y.Z locais além das 2 mais recentes de cada repo (backend/frontend) — a recém-subida e a anterior (rollback). Só toca em tags vX.Y.Z, nunca imagem em uso, e é best-effort (não aborta o deploy). Evita o acúmulo que chegou a dezenas de GB. (O build cache tem limpeza própria: docker builder prune semanal via cron na VPS4 e VPS1.)

  • Por que o modelo importa: acaba a recompilação na promoção (que podia gerar imagem diferente da testada) e a colisão de tags.
  • Implementações de referência: scoreodonto.com (v1.0.40) e newwhats.clube67.com (v1.0.2). O delta do motor está em ../projetos/newwhats.clube67.com/deploy-prod.md.
  • Situações relacionadas: subir-release.md, rollback.md, versionamento.md; infra em ../infra/.