diff --git a/scripts/cms-sync.sh b/scripts/cms-sync.sh index 0e36d67d..4eb5327e 100755 --- a/scripts/cms-sync.sh +++ b/scripts/cms-sync.sh @@ -20,13 +20,17 @@ fi DIRECTION="${1:-}" # push | pull TARGET="${2:-}" # testing | prod SSH_HOST="root@alpha.mintel.me" -DB_USER="${PAYLOAD_DB_USER:-payload}" -DB_NAME="${PAYLOAD_DB_NAME:-payload}" +LOCAL_DB_USER="${PAYLOAD_DB_USER:-payload}" +LOCAL_DB_NAME="${PAYLOAD_DB_NAME:-payload}" LOCAL_DB_CONTAINER="klz-2026-klz-db-1" LOCAL_MEDIA_DIR="./public/media" BACKUP_DIR="./backups" TIMESTAMP=$(date +"%Y%m%d_%H%M%S") +# Remote credentials (resolved per-target from server env files) +REMOTE_DB_USER="" +REMOTE_DB_NAME="" + # Migration names to insert after restore (keeps Payload from prompting) MIGRATIONS=( "20260223_195005_products_collection:1" @@ -42,12 +46,14 @@ resolve_target() { REMOTE_DB_CONTAINER="klz-testing-klz-db-1" REMOTE_APP_CONTAINER="klz-testing-klz-app-1" REMOTE_MEDIA_VOLUME="/var/lib/docker/volumes/klz-testing_klz_media_data/_data" + REMOTE_SITE_DIR="/home/deploy/sites/testing.klz-cables.com" ;; prod|production) REMOTE_PROJECT="klz-cablescom" REMOTE_DB_CONTAINER="klz-cablescom-klz-db-1" REMOTE_APP_CONTAINER="klz-cablescom-klz-app-1" REMOTE_MEDIA_VOLUME="/var/lib/docker/volumes/klz-cablescom_klz_media_data/_data" + REMOTE_SITE_DIR="/home/deploy/sites/klz-cables.com" ;; *) echo "❌ Unknown target: $TARGET" @@ -55,12 +61,40 @@ resolve_target() { exit 1 ;; esac + + # Auto-detect remote DB credentials from the env file on the server + echo "🔍 Detecting $TARGET database credentials..." + REMOTE_DB_USER=$(ssh "$SSH_HOST" "grep -h '^PAYLOAD_DB_USER=' $REMOTE_SITE_DIR/.env* 2>/dev/null | tail -1 | cut -d= -f2" || echo "") + REMOTE_DB_NAME=$(ssh "$SSH_HOST" "grep -h '^PAYLOAD_DB_NAME=' $REMOTE_SITE_DIR/.env* 2>/dev/null | tail -1 | cut -d= -f2" || echo "") + REMOTE_DB_USER="${REMOTE_DB_USER:-payload}" + REMOTE_DB_NAME="${REMOTE_DB_NAME:-payload}" + echo " User: $REMOTE_DB_USER | DB: $REMOTE_DB_NAME" +} + +# ── Ensure local DB is running ───────────────────────────────────────────── +ensure_local_db() { + if ! docker ps --format '{{.Names}}' | grep -q "$LOCAL_DB_CONTAINER"; then + echo "⏳ Local DB container not running. Starting..." + docker compose up -d klz-db + echo "⏳ Waiting for local DB to be ready..." + for i in $(seq 1 10); do + if docker exec "$LOCAL_DB_CONTAINER" pg_isready -U "$LOCAL_DB_USER" -q 2>/dev/null; then + echo "✅ Local DB is ready." + return + fi + sleep 1 + done + echo "❌ Local DB failed to start." + exit 1 + fi } # ── Sanitize migrations table ────────────────────────────────────────────── sanitize_migrations() { local container="$1" - local exec_prefix="$2" # "" for local, "ssh $SSH_HOST" for remote + local db_user="$2" + local db_name="$3" + local is_remote="$4" # "true" or "false" echo "🔧 Sanitizing payload_migrations table..." local SQL="DELETE FROM payload_migrations WHERE batch = -1;" @@ -70,10 +104,10 @@ sanitize_migrations() { SQL="$SQL INSERT INTO payload_migrations (name, batch) SELECT '$name', $batch WHERE NOT EXISTS (SELECT 1 FROM payload_migrations WHERE name = '$name');" done - if [ -z "$exec_prefix" ]; then - docker exec "$container" psql -U "$DB_USER" -d "$DB_NAME" -c "$SQL" + if [ "$is_remote" = "true" ]; then + ssh "$SSH_HOST" "docker exec $container psql -U $db_user -d $db_name -c \"$SQL\"" else - $exec_prefix "docker exec $container psql -U $DB_USER -d $DB_NAME -c \"$SQL\"" + docker exec "$container" psql -U "$db_user" -d "$db_name" -c "$SQL" fi } @@ -82,14 +116,14 @@ backup_local_db() { mkdir -p "$BACKUP_DIR" local file="$BACKUP_DIR/payload_pre_sync_${TIMESTAMP}.sql.gz" echo "📦 Creating safety backup of local DB → $file" - docker exec "$LOCAL_DB_CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" --clean --if-exists | gzip > "$file" + docker exec "$LOCAL_DB_CONTAINER" pg_dump -U "$LOCAL_DB_USER" -d "$LOCAL_DB_NAME" --clean --if-exists | gzip > "$file" echo "✅ Backup: $file ($(du -h "$file" | cut -f1))" } backup_remote_db() { local file="/tmp/payload_pre_sync_${TIMESTAMP}.sql.gz" echo "📦 Creating safety backup of $TARGET DB → $SSH_HOST:$file" - ssh "$SSH_HOST" "docker exec $REMOTE_DB_CONTAINER pg_dump -U $DB_USER -d $DB_NAME --clean --if-exists | gzip > $file" + ssh "$SSH_HOST" "docker exec $REMOTE_DB_CONTAINER pg_dump -U $REMOTE_DB_USER -d $REMOTE_DB_NAME --clean --if-exists | gzip > $file" echo "✅ Remote backup: $file" } @@ -106,23 +140,26 @@ do_push() { echo "" [[ ! $REPLY =~ ^[Yy]$ ]] && { echo "Cancelled."; exit 0; } + # 0. Ensure local DB is running + ensure_local_db + # 1. Safety backup of remote backup_remote_db # 2. Dump local DB echo "📤 Dumping local database..." local dump="/tmp/payload_push_${TIMESTAMP}.sql.gz" - docker exec "$LOCAL_DB_CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" --clean --if-exists | gzip > "$dump" + docker exec "$LOCAL_DB_CONTAINER" pg_dump -U "$LOCAL_DB_USER" -d "$LOCAL_DB_NAME" --clean --if-exists | gzip > "$dump" # 3. Transfer and restore echo "📤 Transferring to $SSH_HOST..." scp "$dump" "$SSH_HOST:/tmp/payload_push.sql.gz" echo "🔄 Restoring database on $TARGET..." - ssh "$SSH_HOST" "gunzip -c /tmp/payload_push.sql.gz | docker exec -i $REMOTE_DB_CONTAINER psql -U $DB_USER -d $DB_NAME --quiet" + ssh "$SSH_HOST" "gunzip -c /tmp/payload_push.sql.gz | docker exec -i $REMOTE_DB_CONTAINER psql -U $REMOTE_DB_USER -d $REMOTE_DB_NAME --quiet" # 4. Sanitize migrations - sanitize_migrations "$REMOTE_DB_CONTAINER" "ssh $SSH_HOST" + sanitize_migrations "$REMOTE_DB_CONTAINER" "$REMOTE_DB_USER" "$REMOTE_DB_NAME" "true" # 5. Sync media echo "🖼️ Syncing media files..." @@ -153,19 +190,22 @@ do_pull() { echo "" [[ ! $REPLY =~ ^[Yy]$ ]] && { echo "Cancelled."; exit 0; } + # 0. Ensure local DB is running + ensure_local_db + # 1. Safety backup of local backup_local_db # 2. Dump remote DB echo "📥 Dumping $TARGET database..." - ssh "$SSH_HOST" "docker exec $REMOTE_DB_CONTAINER pg_dump -U $DB_USER -d $DB_NAME --clean --if-exists | gzip > /tmp/payload_pull.sql.gz" + ssh "$SSH_HOST" "docker exec $REMOTE_DB_CONTAINER pg_dump -U $REMOTE_DB_USER -d $REMOTE_DB_NAME --clean --if-exists | gzip > /tmp/payload_pull.sql.gz" # 3. Transfer and restore echo "📥 Downloading from $SSH_HOST..." scp "$SSH_HOST:/tmp/payload_pull.sql.gz" "/tmp/payload_pull.sql.gz" echo "🔄 Restoring database locally..." - gunzip -c "/tmp/payload_pull.sql.gz" | docker exec -i "$LOCAL_DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" --quiet + gunzip -c "/tmp/payload_pull.sql.gz" | docker exec -i "$LOCAL_DB_CONTAINER" psql -U "$LOCAL_DB_USER" -d "$LOCAL_DB_NAME" --quiet # 4. Sync media echo "🖼️ Syncing media files..."