Files
rx.scoreodonto.com/deploy-prod.sh
T
VPS 4 Deploy Agent 2d94a08c54
build-and-promote / build (push) Has been skipped
build-and-promote / promote (push) Successful in 7m13s
build: registry pela VPN (10.99.0.3:3000), padrão da stack
Migra o RX para o mesmo padrão de scoreodonto/newwhats: imagens publicadas e
puxadas por 10.99.0.3:3000 (WireGuard), não git.clube67.com — o proxy HTTPS
público corta uploads em ~60s, então blobs grandes não sobem por ele. Mesmo
Gitea/storage; verificado que 10.99.0.3:3000/ruicesar/rx-scoreodonto:v2.2.0
entrega o mesmo image id que roda em prod, então o rollback para tags antigas
segue válido.

- build.yml: registry VPN; promote copia o manifest pela API v2 (buildx imagetools
  não fala HTTP) e autentica com o docker login do runner (não há secret
  REGISTRY_TOKEN neste repo).
- docker-compose.prod.yml: image → VPN; ${RX_TAG:?} no lugar de :-latest (sem a
  tag o deploy ABORTA em vez de subir imagem indeterminada).
- deploy-prod.sh: pull pela VPN com fallback à imagem local de tag exata; poda de
  imagens antigas ao fim (mantém as 2 mais recentes, best-effort).

Requer insecure-registries: ["10.99.0.3:3000"] no daemon da VPS1 e do runner
(já configurado para os outros projetos).

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

78 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# =============================================================================
# Deploy por TAG na PRODUÇÃO (VPS1) — rx.scoreodonto.com (modelo build-once/promote)
# Puxa a imagem versionada do registry do Gitea e sobe, SEM build.
#
# Uso (NA VPS1): ./deploy-prod.sh v2.2.0 <commit>
# Rollback: ./deploy-prod.sh <tag-anterior> <commit-anterior>
#
# Pré-requisitos (uma vez): docker login git.clube67.com (token read:package).
# Substitui o modelo antigo (webhook 9003 → build na VPS4 → save/rsync/load).
# =============================================================================
set -euo pipefail
TAG="${1:-}"
COMMIT="${2:-dev}"
if [ -z "$TAG" ]; then
echo "uso: ./deploy-prod.sh <vX.Y.Z> [commit] (ex.: ./deploy-prod.sh v2.2.0 ab12cd3)"
echo "tags disponíveis: git.clube67.com → Packages → rx-scoreodonto"
exit 1
fi
export DOCKER_HOST=unix:///run/user/1000/docker.sock
export RX_TAG="$TAG"
export RX_COMMIT="$COMMIT"
cd "$(dirname "$0")"
FILES="-f docker-compose.yml -f docker-compose.prod.yml"
echo "──────────────────────────────────────────────────────────────"
echo " Deploy rx.scoreodonto.com → PRODUÇÃO tag: $TAG commit: $COMMIT"
echo " Versão exibida (/api/health → badge) injetada em runtime = $TAG"
echo " Volumes preservados: uploads/ processed/ data/ dental-server/updates/ (auto-update dos clients)"
echo "──────────────────────────────────────────────────────────────"
echo "[1/3] pull da imagem $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 app 2>/dev/null; then
echo " pull indisponível — conferindo imagem local com a tag $TAG ..."
img="10.99.0.3:3000/ruicesar/rx-scoreodonto:${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)"
fi
echo "[2/3] subindo (sem build) ..."
docker compose $FILES up -d --no-build app
echo "[3/3] verificação (aguardando boot) ..."
sleep 12
echo -n " health no ar: "
curl -s --max-time 10 https://rx.scoreodonto.com/api/health || echo "(ainda subindo — confira em alguns segundos)"
echo
docker logs rx_scoreodonto_app --tail 5 2>&1 | grep -iE 'VERSION|listen|porta|ready' || 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. Só tags vX.Y.Z; nunca imagem em uso; best-effort.
prune_old_images() {
local keep=2 repo="10.99.0.3:3000/ruicesar/rx-scoreodonto" tag olds inuse
inuse=$(docker ps --format '{{.Image}}' 2>/dev/null | sort -u)
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" ] && return 0
while IFS= read -r tag; do
[ -z "$tag" ] && continue
printf '%s\n' "$inuse" | grep -qxF "$repo:$tag" && continue
docker rmi "$repo:$tag" >/dev/null 2>&1 && echo " removida: $repo:$tag"
done <<< "$olds"
}
prune_old_images || true
echo
echo "✅ Deploy concluído (tag $TAG)."
echo " Rollback: ./deploy-prod.sh <tag-anterior> <commit-anterior>"