From fc0d65fde00937426f365c9547c1b7af28ef5574 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Tue, 16 Jun 2026 09:25:27 +0200 Subject: [PATCH] =?UTF-8?q?feat(deploy):=20deploy=20por=20tag=20na=20produ?= =?UTF-8?q?=C3=A7=C3=A3o=20(Etapa=206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docker-compose.prod.yml: produção roda imagens versionadas do registry (sem build) - deploy-prod.sh : pull da tag + up -d --no-build + verificação /api/version + rollback - deploy.md: Metade A (CI) marcada como FEITA Co-Authored-By: Claude Opus 4.8 --- deploy-prod.sh | 47 +++++++++++++++++++++++++++++++++++++++++ docker-compose.prod.yml | 14 ++++++++++++ documentação/deploy.md | 12 ++++++----- 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100755 deploy-prod.sh create mode 100644 docker-compose.prod.yml diff --git a/deploy-prod.sh b/deploy-prod.sh new file mode 100755 index 0000000..8bcdc87 --- /dev/null +++ b/deploy-prod.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# ============================================================================= +# Deploy por TAG na PRODUÇÃO (VPS1) — Etapa 6 +# Puxa a imagem versionada do registry do Gitea e sobe, SEM build. +# +# Uso (NA VPS1): ./deploy-prod.sh v1.0.13 +# Rollback: ./deploy-prod.sh +# +# Pré-requisitos (uma vez): docker login git.clube67.com (token read:package). +# ============================================================================= +set -euo pipefail + +TAG="${1:-}" +if [ -z "$TAG" ]; then + echo "uso: ./deploy-prod.sh (ex.: ./deploy-prod.sh v1.0.13)" + echo "tags disponíveis no registry: veja git.clube67.com → Packages" + exit 1 +fi + +export DOCKER_HOST=unix:///run/user/1000/docker.sock +export SCOREODONTO_TAG="$TAG" +cd "$(dirname "$0")" +FILES="-f docker-compose.yml -f docker-compose.prod.yml" + +echo "──────────────────────────────────────────────────────────────" +echo " Deploy ScoreOdonto → PRODUÇÃO tag: $TAG" +echo "──────────────────────────────────────────────────────────────" +echo "⚠️ Recomendado: backup do banco antes (dev/prod compartilham o banco):" +echo " ssh deploy@10.99.0.3 'pg_dump -Fc scoreodonto -f ~/backups/scoreodonto_\$(date +%Y%m%d_%H%M).dump'" +echo + +echo "[1/3] pull das imagens $TAG ..." +docker compose $FILES pull scoreodonto-backend scoreodonto-frontend + +echo "[2/3] subindo (sem build) ..." +docker compose $FILES up -d --no-build scoreodonto-backend scoreodonto-frontend nginx + +echo "[3/3] verificação (aguardando boot do backend) ..." +sleep 12 +echo -n " versão no ar: " +curl -s --max-time 10 https://scoreodonto.com/api/version || echo "(ainda subindo — confira em alguns segundos)" +echo +docker logs scoreodontocom-scoreodonto-backend-1 --tail 5 2>&1 | grep -iE 'VERSION|MIGRATION' || true + +echo +echo "✅ Deploy concluído (tag $TAG)." +echo " Rollback: ./deploy-prod.sh " diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..405b020 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,14 @@ +# Override de PRODUÇÃO (VPS1): roda IMAGENS VERSIONADAS do registry em vez de buildar. +# A produção não builda — só consome a imagem pronta publicada pela CI (Etapa 5). +# +# Uso (na VPS1), via deploy-prod.sh , que faz: +# SCOREODONTO_TAG=v1.0.13 docker compose -f docker-compose.yml -f docker-compose.prod.yml pull ... +# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --no-build ... +# +# O --no-build garante que o build: do compose base seja ignorado (usa a imagem puxada). +services: + scoreodonto-backend: + image: git.clube67.com/ruicesar/scoreodonto-backend:${SCOREODONTO_TAG:-latest} + + scoreodonto-frontend: + image: git.clube67.com/ruicesar/scoreodonto-frontend:${SCOREODONTO_TAG:-latest} diff --git a/documentação/deploy.md b/documentação/deploy.md index 370e442..38d832b 100644 --- a/documentação/deploy.md +++ b/documentação/deploy.md @@ -38,13 +38,15 @@ ## 3. As duas metades do fluxo -### Metade A — Integração contínua (push → imagem) 🔜 +### Metade A — Integração contínua (push → imagem) ✅ FEITO 1. Desenvolvedor trabalha na VPS4 e valida em `https://dev.scoreodonto.com`. -2. `git push origin main` para o Gitea (VPS3). -3. A **CI do Gitea** (Gitea Actions) builda a imagem Docker (frontend multi-stage + backend), injetando **versão semântica, commit curto e data de build**. -4. A imagem é enviada ao **Registry privado da VPS3** com tags como `:main`, `:`. +2. `git push origin main` (ou tag `v*`) para o Gitea (VPS3). +3. A **CI do Gitea** (Gitea Actions) builda backend+frontend via `docker compose build`, injetando **versão, commit curto e data de build** (build args → `VITE_*`/`process.env`). +4. As imagens são enviadas ao **Container Registry do Gitea** com tags `:`, `:` e `:latest`. 5. **Nada vai para produção aqui.** Esta metade só produz e guarda o artefato. +> **Implementado em 16/jun/2026.** Workflow: `.gitea/workflows/build.yml`. Runner: `vps4-builder` (act_runner 0.6.1, **modo host** com Docker, serviço systemd `act_runner` na VPS4, label `self-hosted`). Login no registry usa o secret `REGISTRY_TOKEN` se presente, senão a credencial do host. Validado: push na main → build → `scoreodonto-{backend,frontend}:v1.0.13`/`:`/`:latest` publicados. + ### Metade B — Entrega por tag (tag → produção) 🔜 1. Quando uma versão está aprovada, cria-se uma **tag semântica**: `git tag v1.0.15 && git push origin v1.0.15`. 2. A CI marca a imagem correspondente como `:v1.0.15` no registry (promoção do artefato já testado — sem rebuild). @@ -94,7 +96,7 @@ Visível no **rodapé** da aplicação, em um **endpoint de diagnóstico** (ex.: |-------|---------|--------| | 3 | Versionamento visível (rodapé + endpoint + log) | ✅ | | 4 | Registry Docker privado na VPS3 | ✅ (Gitea Container Registry — ver `REGISTRY.md`) | -| 5 | Pipeline de build no Gitea (push → imagem → registry), **sem deploy** | 🔜 | +| 5 | Pipeline de build no Gitea (push → imagem → registry), **sem deploy** | ✅ (`.gitea/workflows/build.yml` + runner `vps4-builder`) | | 6 | Deploy por TAG (`vX.Y.Z` → produção na VPS1) + rollback por imagem | 🔜 | Quando as Etapas 3–6 estiverem prontas, este documento deixa de ter marcações 🔜 e passa a descrever o fluxo corrente.