#!/usr/bin/env bash # ──────────────────────────────────────────────────────────────────────────── # Asset Sync Tool # Syncs media files between environments without touching the database. # ──────────────────────────────────────────────────────────────────────────── set -euo pipefail # Load environment variables if [ -f .env ]; then set -a; source .env; set +a fi # ── Configuration ────────────────────────────────────────────────────────── SOURCE_ENV="${1:-}" # local | testing | staging | prod TARGET_ENV="${2:-}" # testing | staging | prod SSH_HOST="root@alpha.mintel.me" LOCAL_MEDIA_DIR="./public/media" DRY_RUN="" CHECKSUM="" if [[ "$*" == *"--dry-run"* ]]; then DRY_RUN="--dry-run" echo "🏃 DRY RUN MODE ENABLED" fi if [[ "$*" == *"--checksum"* ]]; then CHECKSUM="-c" echo "🔍 CHECKSUM MODE ENABLED (Slower but more reliable)" fi # ── Resolve Paths ────────────────────────────────────────────────────────── get_media_path() { case "$1" in local) echo "$LOCAL_MEDIA_DIR" ;; testing) echo "/var/lib/docker/volumes/klz-testing_klz_media_data/_data" ;; staging) echo "/var/lib/docker/volumes/klz-staging_klz_media_data/_data" ;; prod|production) echo "/var/lib/docker/volumes/klz-cablescom_klz_media_data/_data" ;; *) echo "❌ Unknown environment: $1"; exit 1 ;; esac } get_app_container() { case "$1" in testing) echo "klz-testing-klz-app-1" ;; staging) echo "klz-staging-klz-app-1" ;; prod|production) echo "klz-cablescom-klz-app-1" ;; *) echo "" ;; esac } SRC_PATH=$(get_media_path "$SOURCE_ENV") TGT_PATH=$(get_media_path "$TARGET_ENV") TGT_CONTAINER=$(get_app_container "$TARGET_ENV") echo "🚀 Syncing assets: $SOURCE_ENV → $TARGET_ENV" echo "📂 Source: $SRC_PATH" echo "📂 Target: $TGT_PATH" # ── Execution ────────────────────────────────────────────────────────────── if [[ ! -d "$SRC_PATH" ]] && [[ "$SOURCE_ENV" == "local" ]]; then echo "❌ Source directory does not exist: $SRC_PATH" exit 1 fi if [[ "$SOURCE_ENV" == "local" ]]; then # Local → Remote echo "📡 Running rsync..." rsync -avzi $CHECKSUM --delete --progress $DRY_RUN "$SRC_PATH/" "$SSH_HOST:$TGT_PATH/" elif [[ "$TARGET_ENV" == "local" ]]; then # Remote → Local mkdir -p "$LOCAL_MEDIA_DIR" echo "📡 Running rsync..." rsync -avzi $CHECKSUM --delete --progress $DRY_RUN "$SSH_HOST:$SRC_PATH/" "$TGT_PATH/" else # Remote → Remote (e.g., testing → staging) echo "📡 Running remote rsync..." ssh "$SSH_HOST" "rsync -avzi $CHECKSUM --delete --progress $DRY_RUN $SRC_PATH/ $TGT_PATH/" fi # Fix ownership on remote target if it's not local if [[ "$TARGET_ENV" != "local" && -z "$DRY_RUN" ]]; then echo "🔑 Fixing media file permissions on $TARGET_ENV..." ssh "$SSH_HOST" "docker exec -u 0 $TGT_CONTAINER chown -R 1001:65533 /app/public/media/ 2>/dev/null || true" fi echo "✅ Asset sync complete!"