#!/usr/bin/env bash set -euo pipefail HOST="${HOST:-root@76.13.31.179}" APP_DIR="${APP_DIR:-/opt/skg-marketing-studio}" BACKUP_DIR="${BACKUP_DIR:-/opt/skg-marketing-studio-backups}" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT_DIR" if [[ "${1:-}" == "--no-build" ]]; then BUILD_FLAG="" else BUILD_FLAG="--build" fi echo "==> Preflight: creating remote data/env backup" ssh "$HOST" "set -euo pipefail cd '$APP_DIR' mkdir -p '$BACKUP_DIR' stamp=\$(date +%Y%m%d%H%M%S) tar -czf '$BACKUP_DIR/skg-marketing-preserve-'\$stamp'.tgz' \ deploy/.env.production \ data/jobs \ data/asset_library \ data/prompt_library \ data/_trash \ secrets 2>/tmp/skg-backup-warnings.log || { cat /tmp/skg-backup-warnings.log >&2 || true exit 1 } find '$BACKUP_DIR' -name 'skg-marketing-preserve-*.tgz' -type f -printf '%T@ %p\n' | sort -nr | tail -n +8 | cut -d' ' -f2- | xargs -r rm -f echo backup:\$(ls -t '$BACKUP_DIR'/skg-marketing-preserve-*.tgz | head -1) " echo "==> Syncing code with production data protected" rsync -az --delete \ --filter='P /data/***' \ --filter='P /jobs/***' \ --filter='P /secrets/***' \ --filter='P /deploy/.env.production' \ --filter='P /api/jobs/***' \ --filter='P /api/.env' \ --filter='P /api/.env.local' \ --filter='P /api/.env.production' \ --exclude='/.git/' \ --exclude='/.memory/' \ --exclude='/.logs/' \ --exclude='/.pids/' \ --exclude='/data/' \ --exclude='/jobs/' \ --exclude='/secrets/' \ --exclude='/api/jobs/' \ --exclude='/api/.env' \ --exclude='/api/.env.local' \ --exclude='/api/.env.production' \ --exclude='/deploy/.env.production' \ --exclude='/web/node_modules/' \ --exclude='/web/.next/' \ --exclude='/web/out/' \ --exclude='/node_modules/' \ --exclude='内部分享-口播脚本.md' \ ./ "$HOST:$APP_DIR/" echo "==> Rebuilding production containers" ssh "$HOST" "cd '$APP_DIR' && docker compose -f docker-compose.prod.yml --env-file deploy/.env.production up -d $BUILD_FLAG" echo "==> Verifying production" "$ROOT_DIR/scripts/verify-prod-docker.sh" "$HOST" echo "==> Done"