#!/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 " Versão exibida (/api/version) será injetada em runtime = $TAG (commit/build vêm da imagem)" echo "──────────────────────────────────────────────────────────────" echo "⚠️ Recomendado: backup do banco de PRODUÇÃO antes (migrações rodam no boot do backend):" 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 (registry pela VPN) ..." # Registry = 10.99.0.3:3000 (WireGuard). Se o pull falhar (VPN fora do ar), exigimos # a imagem local COM A TAG EXATA — nunca caímos para :latest. if ! docker compose $FILES pull scoreodonto-backend scoreodonto-frontend 2>/dev/null; then echo " pull indisponível — conferindo imagens locais com a tag $TAG ..." for app in backend frontend; do img="10.99.0.3:3000/ruicesar/scoreodonto-${app}:${TAG}" docker image inspect "$img" >/dev/null 2>&1 || { echo "ERRO: $img não existe nem no registry nem localmente." echo " Confira a VPN (ping 10.99.0.3)." exit 1 } echo " ok: $img (local)" done fi 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 "[poda] removendo imagens antigas (mantém as 2 versões mais recentes) ..." # Política "atual + 1 anterior": após deployar, apaga as imagens vX.Y.Z locais # além das 2 mais recentes de cada repo — a atual (recém-subida) e a anterior # (rollback). Best-effort: roda com tudo já no ar e NUNCA aborta o deploy. prune_old_images() { local keep=2 repo tag olds inuse inuse=$(docker ps --format '{{.Image}}' 2>/dev/null | sort -u) for repo in "$@"; do olds=$(docker images --format '{{.Tag}}' "$repo" 2>/dev/null \ | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | head -n -"$keep") || true [ -z "$olds" ] && continue while IFS= read -r tag; do [ -z "$tag" ] && continue printf '%s\n' "$inuse" | grep -qxF "$repo:$tag" && continue # nunca em uso docker rmi "$repo:$tag" >/dev/null 2>&1 && echo " removida: $repo:$tag" done <<< "$olds" done } prune_old_images \ 10.99.0.3:3000/ruicesar/scoreodonto-backend \ 10.99.0.3:3000/ruicesar/scoreodonto-frontend || true echo echo "✅ Deploy concluído (tag $TAG)." echo " Rollback: ./deploy-prod.sh "