docs: aponta deploy/infra para documentos-unicos (fonte única); remove DEPLOY-PRODUCAO local
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# LEIA
|
||||
|
||||
A documentação de **infra/deploy** deste projeto **NÃO fica aqui**. Fonte única em:
|
||||
|
||||
**`/home/deploy/stack/documentos-unicos/`** — comece pelo `LEIA-PRIMEIRO.md`.
|
||||
|
||||
- Deploy: `documentos-unicos/deploy/` (modelo, subir-release, rollback, versionamento)
|
||||
- Infra: `documentos-unicos/infra/` (máquinas/rede, ambiente-dev)
|
||||
|
||||
Documentação **específica do ScoreOdonto** (produto, RX, banco-dev, registry) está em `doc/` deste projeto.
|
||||
|
||||
**Regra:** nunca criar documentação de deploy/infra solta no projeto; atualização vai na pasta única (reescrever; antigo → `desuso/`). Tudo em português.
|
||||
@@ -1,117 +0,0 @@
|
||||
# Deploy & Versionamento — Runbook ScoreOdonto
|
||||
|
||||
> Auditado contra o sistema em **17/jun/2026**. Cada item carrega seu **status real**.
|
||||
>
|
||||
> **Legenda:** ✅ EM PRODUÇÃO · 🧪 EM DEV (não promovido) · 🎯 ALVO (não implementado).
|
||||
>
|
||||
> **Produção AGORA:** `v1.0.16 · commit 471c2c2 · 2026-06-17` (`curl https://scoreodonto.com/api/version`).
|
||||
> Modelo **Build Once → Promote → Deploy** completo — Passo 5 validado em v1.0.16. Tudo abaixo ✅.
|
||||
|
||||
---
|
||||
|
||||
## 1. O modelo ✅
|
||||
|
||||
> **Push** na `main` builda **uma vez** e publica por **commit**; a **tag `vX.Y.Z`** **re-tagueia** esse mesmo artefato (sem rebuild) e deploya. **Produção nunca builda — só executa imagens.**
|
||||
|
||||
```
|
||||
PUSH main (commit C) TAG vX.Y.Z (no commit C)
|
||||
│ │
|
||||
▼ ▼
|
||||
CI: build (1x) CI: promote (SEM build) ✅
|
||||
publica :C + :latest re-tag :C → :vX.Y.Z (MESMO digest) + deploy
|
||||
▼ ▼
|
||||
registry VPS1: pull :vX.Y.Z + up --no-build
|
||||
APP_VERSION=tag injetada em runtime
|
||||
```
|
||||
Prova (v1.0.16): `:v1.0.16` tem **digest idêntico** a `:471c2c2` — a tag é só um rótulo sobre a imagem já testada.
|
||||
|
||||
---
|
||||
|
||||
## 2. Estado por componente (verificado)
|
||||
|
||||
| Componente | Status | Detalhe |
|
||||
|---|---|---|
|
||||
| Infra VPS1/3/4 + Docker rootless | ✅ | Mapa na §3 |
|
||||
| Registry (`git.clube67.com/ruicesar/...`) | ✅ | Ver `REGISTRY.md` |
|
||||
| CI: job `build` publica por **commit** em push (sem `APP_VERSION`) | ✅ | `.gitea/workflows/build.yml` (runner `vps4-builder`) |
|
||||
| Job `promote` por tag: re-tag `:<commit>→:vX.Y.Z` (sem rebuild) + deploy | ✅ | validado em v1.0.16 (`:v1.0.16` == `:471c2c2`) |
|
||||
| Validação de integridade no promote (commit existe? digest igual? front+back mesmo commit) | ✅ | falha se o commit não foi pushado |
|
||||
| Produção não builda (`image:` + `pull` + `up --no-build`) | ✅ | `docker-compose.prod.yml` |
|
||||
| Banco DEV isolado em `pgdev`; prod no Postgres da VPS3 | ✅ | Ver `BANCO-DEV-ESTRATEGIA.md` |
|
||||
| Versão em runtime (`/api/version`) → Configurações + telas públicas | ✅ | `useAppVersion()`; sem `APP_VERSION` manual |
|
||||
| `APP_VERSION`/`APP_ENV` injetados no deploy em runtime | ✅ | `compose.prod` `environment` |
|
||||
| Versão **nasce da tag git** (`constants.ts`/`update-version.js` removidos) | ✅ | Passo 5 |
|
||||
|
||||
---
|
||||
|
||||
## 3. Mapa de máquinas ✅
|
||||
|
||||
| Onde | Host | Papel | Docker |
|
||||
|---|---|---|---|
|
||||
| VPS1 | `10.99.0.1` | **Produção** (Traefik + apps) | rootless |
|
||||
| VPS3 | `10.99.0.3` | Postgres (prod) + Gitea + registry | — |
|
||||
| VPS4 | `10.99.0.4` | **Dev + Builder** (código; runner CI; `pgdev`) | rootless |
|
||||
|
||||
- Repo: `ssh://git@10.99.0.3/ruicesar/scoreodonto.com.git`. Project Compose: `scoreodontocom`.
|
||||
|
||||
---
|
||||
|
||||
## 4. De onde vem a versão (`/api/version`)
|
||||
|
||||
```json
|
||||
{ "name": "ScoreOdonto API", "version": "v1.0.16", "commit": "471c2c2",
|
||||
"build": "2026-06-17 10:35 UTC", "environment": "PROD" }
|
||||
```
|
||||
- **commit / build** = carimbados no **build** (imutáveis — identidade do artefato).
|
||||
- **version / environment** = **injetados no deploy em runtime** (a partir da tag). A mesma imagem é promovida sob qualquer tag, sem rebuild.
|
||||
- **Frontend** lê tudo de `/api/version` (`useAppVersion()`); não embute versão. Fonte única = backend.
|
||||
|
||||
---
|
||||
|
||||
## 5. Runbook — subir um release ✅
|
||||
|
||||
> ⚠️ **Regra de ouro:** confirme **DEV ou PRODUÇÃO**. `dev.scoreodonto.com` = VPS4 (banco `pgdev`). `scoreodonto.com` = VPS1 (real). **Nunca** `git push --force` na `main`. Push/tag exigem autorização explícita.
|
||||
|
||||
```bash
|
||||
# 1) VPS4: validar em DEV
|
||||
cd /home/deploy/stack/scoreodonto.com
|
||||
node --check backend/server.js
|
||||
docker compose build scoreodonto-backend scoreodonto-frontend
|
||||
docker compose up -d --force-recreate scoreodonto-backend scoreodonto-frontend # https://dev.scoreodonto.com
|
||||
|
||||
# 2) commit + push → CI builda 1x e publica :<commit> + :latest (NÃO deploya)
|
||||
git add -A && git commit -m "feat: <descrição>"
|
||||
git push origin main
|
||||
|
||||
# 3) tag = "aprovado p/ produção" → job PROMOTE re-tagueia :<commit>→:vX.Y.Z (SEM rebuild) + deploya
|
||||
# (o número da versão é livre — não precisa casar com nenhum arquivo)
|
||||
git tag -a vX.Y.Z -m "release vX.Y.Z" && git push origin vX.Y.Z
|
||||
|
||||
# 4) verificar (sem SSH)
|
||||
curl -s https://scoreodonto.com/api/version # → vX.Y.Z · <commit> · PROD
|
||||
```
|
||||
|
||||
**Backup do banco de PRODUÇÃO antes de releases sensíveis** (via container, pois não há shell na VPS3):
|
||||
```bash
|
||||
docker run --rm -e PGPASSWORD=<senha> -v /home/deploy/backups:/b postgres:18 \
|
||||
pg_dump -h 10.99.0.3 -U scoreodonto_user -d scoreodonto -Fc -f /b/scoreodonto_$(date +%Y%m%d_%H%M).dump
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Rollback ✅
|
||||
|
||||
Por imagem, **sem rebuild** — na VPS1:
|
||||
```bash
|
||||
/home/deploy/stack/scoreodonto.com/deploy-prod.sh <tag-ou-commit-anterior> # pull + up --no-build
|
||||
```
|
||||
⚠️ A referência confiável é o **commit** (`:<sha>`). Tags `:vX.Y.Z` antigas (pré-Passo 5) podem ter sido republicadas com código diferente — a partir do Passo 5, `:vX.Y.Z` é sempre um alias imutável do commit. Migrações são aditivas (voltar o código é seguro). Dump em `/home/deploy/backups/` só em extremo.
|
||||
|
||||
---
|
||||
|
||||
## 7. Follow-ups (não bloqueiam) 🎯
|
||||
- `GET /api/health` (monitoramento/diagnóstico).
|
||||
- **Política de retenção** do registry (uma imagem `:<commit>` por push acumula).
|
||||
- Reconciliar o repo na VPS1 (working tree sujo, não afeta o deploy por imagem).
|
||||
|
||||
Racional do modelo em `deploy.md`; histórico em `project-cicd-tag-promove-nao-rebuilda` (memória).
|
||||
Reference in New Issue
Block a user