#!/bin/bash set -euo pipefail WORKDIR="${1:-$(pwd)}" COMPOSE_FILE="${WORKDIR}/docker-compose.yml" echo "DEBUG: Looking for Compose file at $COMPOSE_FILE" ls -l "$COMPOSE_FILE" || echo "⚠️ File not found!" if [[ ! -f "$COMPOSE_FILE" ]]; then echo "❌ No docker-compose.yml found in $WORKDIR" exit 1 fi # Determine project name (Docker Compose style) PROJECT_NAME=$(basename "$WORKDIR") echo "📦 Working in (${PROJECT_NAME})" # Get original user details (in case script is run via sudo -E or similar) ORIGINAL_USER="${SUDO_USER:-$USER}" ORIGINAL_UID=$(id -u "$ORIGINAL_USER") ORIGINAL_GID=$(id -g "$ORIGINAL_USER") # Get services SERVICE_NAMES=$(yq e '.services | keys | .[]' "$COMPOSE_FILE") for SERVICE in $SERVICE_NAMES; do echo "🔍 Found service (${SERVICE})" # Get service volumes VOLUMES=$(yq e ".services.${SERVICE}.volumes[]" "$COMPOSE_FILE" 2>/dev/null || true) while IFS= read -r VOLUME; do # Clean up quotes/whitespace VOLUME=$(echo "$VOLUME" | sed 's/^"//;s/"$//;s/^[[:space:]]*//;s/[[:space:]]*$//') # Skip bind mounts if [[ "$VOLUME" == ./* || "$VOLUME" == /* ]]; then continue fi SOURCE=$(echo "$VOLUME" | cut -d':' -f1) echo "📁 Found named volume (${SOURCE})" read -rp "→ Tar.gz and save as ${SOURCE}.tar.gz? (Y/n) " REPLY REPLY=${REPLY:-Y} if [[ "$REPLY" =~ ^[Yy]$ ]]; then VOLUME_PATH="/var/lib/docker/volumes/${PROJECT_NAME}_${SOURCE}/_data" OUTPUT_FILE="${WORKDIR}/${SOURCE}.tar.gz" if ! sudo test -d "$VOLUME_PATH"; then echo "⚠️ Volume path not found: $VOLUME_PATH" continue fi echo "📦 Backing up $VOLUME_PATH → $OUTPUT_FILE" # Use sudo to read, but write file as your user sudo tar -czf "$OUTPUT_FILE" -C "$VOLUME_PATH" . # Fix ownership in case sudo did anything funny chown "$ORIGINAL_UID:$ORIGINAL_GID" "$OUTPUT_FILE" echo "✅ Backup done: $OUTPUT_FILE" else echo "⏭️ Skipping ${SOURCE}" fi done <<< "$VOLUMES" done