diff --git a/backup_named_volumes.sh b/backup_named_volumes.sh new file mode 100644 index 0000000..e6219e7 --- /dev/null +++ b/backup_named_volumes.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# Auto-elevate if not root +if [[ "$EUID" -ne 0 ]]; then + echo "This script needs root to access Docker volumes. Re-running with sudo..." + exec sudo "$0" "$@" +fi + +set -euo pipefail + +WORKDIR="$(pwd)" +COMPOSE_FILE="${WORKDIR}/docker-compose.yml" + +if [[ ! -f "$COMPOSE_FILE" ]]; then + echo "❌ No docker-compose.yml found in $WORKDIR" + exit 1 +fi + +# Original user info (for restoring file ownership) +ORIGINAL_USER="${SUDO_USER:-$USER}" +ORIGINAL_UID=$(id -u "$ORIGINAL_USER") +ORIGINAL_GID=$(id -g "$ORIGINAL_USER") + +# Determine the project name (same as docker-compose uses) +PROJECT_NAME=$(basename "$WORKDIR") + +echo "📦 Working in (${PROJECT_NAME})" + +# Get all services using yq +SERVICE_NAMES=$(yq e '.services | keys | .[]' "$COMPOSE_FILE") + +for SERVICE in $SERVICE_NAMES; do + echo "🔍 Found service (${SERVICE})" + + # Get the volumes for the service + VOLUMES=$(yq e ".services.${SERVICE}.volumes[]" "$COMPOSE_FILE" 2>/dev/null || true) + + while IFS= read -r VOLUME; do + # Clean up quotes and whitespace + VOLUME=$(echo "$VOLUME" | sed 's/^"//;s/"$//;s/^[[:space:]]*//;s/[[:space:]]*$//') + + # Skip bind mounts + if [[ "$VOLUME" == ./* || "$VOLUME" == /* ]]; then + continue + fi + + # Get the source volume name (before colon) + SOURCE=$(echo "$VOLUME" | cut -d':' -f1) + + echo "📁 Found named volume (${SOURCE})" + + # Prompt the user + read -rp "→ Would you like to tar.gz and save to this location as ${SOURCE}.tar.gz? (Y/n) " REPLY + REPLY=${REPLY:-Y} + + if [[ "$REPLY" =~ ^[Yy]$ ]]; then + VOLUME_PATH="/var/lib/docker/volumes/${PROJECT_NAME}_${SOURCE}/_data" + + if [[ ! -d "$VOLUME_PATH" ]]; then + echo "⚠️ Volume path $VOLUME_PATH not found! Skipping..." + continue + fi + + OUTPUT_FILE="${WORKDIR}/${SOURCE}.tar.gz" + + echo "📦 Backing up $VOLUME_PATH to $OUTPUT_FILE" + + # Create tar as original user + sudo -u "$ORIGINAL_USER" tar -czf "$OUTPUT_FILE" -C "$VOLUME_PATH" . + + # Ensure file is owned properly + chown "$ORIGINAL_UID:$ORIGINAL_GID" "$OUTPUT_FILE" + + echo "✅ Backup complete: $OUTPUT_FILE" + else + echo "⏭️ Skipping ${SOURCE}" + fi + + done <<< "$VOLUMES" +done