#!/bin/bash # Auto-deploy script for vreau.digital # Triggered by Gitea webhook on push to main. # # Secrets: NOT in this script, NOT in .env. All app secrets fetched at runtime # from Infisical (project beletage-infra, env prod, path /vreaudigital) using # the Machine Identity credentials in .infisical-mi (perm 600, never committed). # # Build args injected: BUILD_SHA, BUILD_REF, BUILD_TIME — exposed by /api/version. set -euo pipefail DEPLOY_DIR="/opt/vreau-digital" LOG_FILE="/var/log/vreau-digital-deploy.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } log "=== Deploy started ===" cd "$DEPLOY_DIR" # Sanity: MI creds must exist before we even try to build the new image if [ ! -s "$DEPLOY_DIR/.infisical-mi" ]; then log "ERROR: $DEPLOY_DIR/.infisical-mi missing or empty — aborting." exit 1 fi log "Pulling latest changes from Gitea..." git pull --ff-only origin main 2>&1 | tee -a "$LOG_FILE" BUILD_SHA="$(git rev-parse --short HEAD)" BUILD_REF="$(git rev-parse --abbrev-ref HEAD)" BUILD_TIME="$(date -u +%FT%TZ)" export BUILD_SHA BUILD_REF BUILD_TIME log "Build args: SHA=$BUILD_SHA REF=$BUILD_REF TIME=$BUILD_TIME" log "Rebuilding Docker image..." docker compose build --pull 2>&1 | tee -a "$LOG_FILE" log "Restarting container..." docker compose up -d 2>&1 | tee -a "$LOG_FILE" # Wait briefly, verify /api/version reports the new SHA sleep 4 ACTUAL=$(curl -fs --max-time 5 http://localhost:5095/api/version 2>/dev/null | grep -oE '"sha":"[^"]+"' | cut -d'"' -f4 || echo "") if [ "$ACTUAL" = "$BUILD_SHA" ]; then log "SUCCESS: /api/version reports sha=$ACTUAL" else log "WARN: /api/version sha mismatch (expected=$BUILD_SHA, got=$ACTUAL) — container may still be starting" fi log "Pruning dangling images..." docker image prune -f 2>&1 | tee -a "$LOG_FILE" log "=== Deploy complete (sha=$BUILD_SHA) ==="