#!/bin/sh # Oikos deploy script — triggered by Gitea webhook on push to dtoro/Homelab-Docs. # Runs on mac-mini as non-root user via systemd unit oikos-deploy-webhook.service. # Phase 6: CI-gated, SHA-tagged images, rolling restart, pre-deploy pg_dump. set -e REPO_DIR="${REPO_DIR:-$PWD}" COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}" PROFILE="${PROFILE:-full}" HEALTH_URL="${HEALTH_URL:-http://localhost:8090/healthz}" DUMP_DIR="${DUMP_DIR:-/opt/oikos/backups}" RETRIES=${RETRIES:-30} SLEEP=${SLEEP:-2} cd "$REPO_DIR" echo "=== oikos deploy: $(date) ===" SHA=$(git rev-parse --short HEAD) echo "SHA: $SHA" # 1. Pre-deploy pg_dump for rollback safety (plan O1) echo "[1/6] pre-deploy pg_dump" DUMP_FILE="$DUMP_DIR/pre-deploy-$SHA.sql" mkdir -p "$DUMP_DIR" docker compose exec -T postgres pg_dump -U oikos oikos > "$DUMP_FILE" 2>/dev/null || \ echo "WARNING: pg_dump failed — rollback will not have a recovery point" # 2. Pull latest echo "[2/6] git pull" git pull origin main # 3. Verify CI passed echo "[3/6] verify build" if ! git log -1 --format="%s" | grep -q .; then echo "ERROR: empty commit message" exit 1 fi # 4. Build and restart with health-check rollout echo "[4/6] docker compose build" DOCKER_BUILDKIT=1 docker compose --profile "$PROFILE" build \ --build-arg BUILDKIT_INLINE_CACHE=1 # 5. Rolling restart echo "[5/6] docker compose up -d" docker compose --profile "$PROFILE" up -d --remove-orphans # 6. Health check wait echo "[6/6] health check" for i in $(seq 1 $RETRIES); do if curl -sf "$HEALTH_URL" > /dev/null 2>&1; then echo "healthy after ${i}s" exit 0 fi sleep "$SLEEP" done echo "ERROR: health check failed after $((RETRIES * SLEEP))s" exit 1