feat: Add bash completion for backup scripts and enhance README documentation

This commit is contained in:
Peter Wood
2025-05-27 22:11:14 -04:00
parent a4f6a8aeed
commit 502beec7e2
8 changed files with 835 additions and 13 deletions

View File

@@ -51,6 +51,80 @@ if [ -z "$DB_USERNAME" ] || [ -z "$DB_DATABASE_NAME" ] || [ -z "$UPLOAD_LOCATION
exit 1
fi
# Help function
show_help() {
cat << EOF
Immich Complete Backup Script
This script creates a complete backup of the Immich installation including:
1. Postgres database (using pg_dumpall as recommended by Immich)
2. User upload directories (photos, videos, and metadata)
USAGE:
$(basename "$0") [OPTIONS]
OPTIONS:
--help, -h Show this help message and exit
--dry-run Show what would be backed up without performing actual backup
--no-upload Skip B2 upload (local backup only)
--verbose Enable verbose logging
CONFIGURATION:
This script requires a .env file in the parent directory with:
- DB_USERNAME=<database_username>
- DB_DATABASE_NAME=<database_name>
- UPLOAD_LOCATION=<path_to_upload_directory>
OPTIONAL B2 CONFIGURATION:
- B2_APPLICATION_KEY_ID=<your_b2_app_key_id>
- B2_APPLICATION_KEY=<your_b2_app_key>
- B2_BUCKET_NAME=<your_b2_bucket_name>
OPTIONAL WEBHOOK CONFIGURATION:
- WEBHOOK_URL=<your_notification_webhook_url>
EXAMPLES:
$(basename "$0") # Run full backup
$(basename "$0") --help # Show this help
$(basename "$0") --dry-run # Preview backup without executing
$(basename "$0") --no-upload # Backup locally only (skip B2)
RESTORE INSTRUCTIONS:
https://immich.app/docs/administration/backup-and-restore/
EOF
}
# Parse command line arguments
DRY_RUN=false
NO_UPLOAD=false
VERBOSE=false
while [[ $# -gt 0 ]]; do
case $1 in
--help|-h)
show_help
exit 0
;;
--dry-run)
DRY_RUN=true
shift
;;
--no-upload)
NO_UPLOAD=true
shift
;;
--verbose)
VERBOSE=true
shift
;;
*)
echo "Error: Unknown option $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# B2 CLI tool path
B2_CLI="$(dirname "$0")/b2-linux"
@@ -143,6 +217,68 @@ DB_BACKUP_FILENAME="immich_db_backup_${TIMESTAMP}.sql"
DB_BACKUP_PATH="${BACKUP_DIR}/${DB_BACKUP_FILENAME}"
UPLOAD_BACKUP_PATH="${BACKUP_DIR}/immich_uploads_${TIMESTAMP}.tar.gz"
# Handle dry-run mode
if [ "$DRY_RUN" = true ]; then
echo ""
echo "=== DRY RUN MODE - NO ACTUAL BACKUP WILL BE PERFORMED ==="
echo ""
echo "Configuration:"
echo " - Database: ${DB_DATABASE_NAME}"
echo " - Username: ${DB_USERNAME}"
echo " - Upload Location: ${UPLOAD_LOCATION}"
echo " - Container: immich_postgres"
echo " - Backup Directory: ${BACKUP_DIR}"
echo ""
echo "Would create:"
echo " - Database backup: ${DB_BACKUP_PATH}.gz"
echo " - Upload backup: ${UPLOAD_BACKUP_PATH}"
echo ""
# Check container status in dry-run
echo "Container Status Check:"
if docker ps -q --filter "name=immich_server" | grep -q .; then
echo " ✓ immich_server: Running (would pause during backup)"
else
echo " ! immich_server: Not running or not found"
fi
if docker ps -q --filter "name=immich_postgres" | grep -q .; then
echo " ✓ immich_postgres: Running"
else
echo " ✗ immich_postgres: Not running - backup would fail!"
exit 1
fi
# Check upload directory
if [ -d "${UPLOAD_LOCATION}" ]; then
UPLOAD_SIZE=$(du -sh "${UPLOAD_LOCATION}" 2>/dev/null | cut -f1 || echo "unknown")
echo " ✓ Upload directory: ${UPLOAD_LOCATION} (${UPLOAD_SIZE})"
else
echo " ✗ Upload directory: ${UPLOAD_LOCATION} does not exist - backup would fail!"
exit 1
fi
# Check B2 configuration
echo ""
echo "B2 Upload Configuration:"
if [ "$NO_UPLOAD" = true ]; then
echo " ! B2 upload disabled by --no-upload flag"
elif [ -n "$B2_APPLICATION_KEY_ID" ] && [ -n "$B2_APPLICATION_KEY" ] && [ -n "$B2_BUCKET_NAME" ]; then
echo " ✓ B2 configured - would upload to bucket: ${B2_BUCKET_NAME}"
if [ -f "$B2_CLI" ]; then
echo " ✓ B2 CLI found at: ${B2_CLI}"
else
echo " ✗ B2 CLI not found at: ${B2_CLI} - upload would fail!"
fi
else
echo " ! B2 not configured - would skip upload"
fi
echo ""
echo "=== DRY RUN COMPLETE - No files were created or modified ==="
exit 0
fi
log_message "Starting complete backup of Immich installation..."
log_message "Using settings from .env file:"
log_message " - Database: ${DB_DATABASE_NAME}"
@@ -151,6 +287,14 @@ log_message " - Upload Location: ${UPLOAD_LOCATION}"
log_message " - Container: immich_postgres"
log_message " - Backup Directory: ${BACKUP_DIR}"
if [ "$NO_UPLOAD" = true ]; then
log_message " - B2 Upload: DISABLED (--no-upload flag)"
fi
if [ "$VERBOSE" = true ]; then
log_message " - Verbose logging: ENABLED"
fi
# Send start notification
send_notification "🚀 Immich Backup Started" "Starting complete backup of Immich database and uploads directory" "info"
@@ -271,19 +415,25 @@ echo "=== BACKUP SUMMARY ==="
echo "Database backup size: ${DB_BACKUP_SIZE}"
echo "Upload directory backup size: ${UPLOAD_BACKUP_SIZE}"
# Upload to B2 (if configured)
# Upload to B2 (if configured and not disabled)
echo ""
echo "=== UPLOADING TO BACKBLAZE B2 ==="
B2_UPLOAD_SUCCESS=true
if [ "$NO_UPLOAD" = true ]; then
echo "=== SKIPPING B2 UPLOAD (--no-upload flag) ==="
log_message "B2 upload skipped due to --no-upload flag"
B2_UPLOAD_SUCCESS="skipped"
else
echo "=== UPLOADING TO BACKBLAZE B2 ==="
B2_UPLOAD_SUCCESS=true
# Upload database backup
if ! upload_to_b2 "${DB_BACKUP_PATH}.gz"; then
B2_UPLOAD_SUCCESS=false
fi
# Upload database backup
if ! upload_to_b2 "${DB_BACKUP_PATH}.gz"; then
B2_UPLOAD_SUCCESS=false
fi
# Upload uploads backup
if ! upload_to_b2 "${UPLOAD_BACKUP_PATH}"; then
B2_UPLOAD_SUCCESS=false
# Upload uploads backup
if ! upload_to_b2 "${UPLOAD_BACKUP_PATH}"; then
B2_UPLOAD_SUCCESS=false
fi
fi
# Prepare notification message
@@ -292,7 +442,11 @@ UPLOAD_FILENAME=$(basename "${UPLOAD_BACKUP_PATH}")
NOTIFICATION_MESSAGE="📦 Database: ${DB_FILENAME} (${DB_BACKUP_SIZE})
📁 Uploads: ${UPLOAD_FILENAME} (${UPLOAD_BACKUP_SIZE})"
if [ "$B2_UPLOAD_SUCCESS" = true ] && [ -n "$B2_BUCKET_NAME" ]; then
if [ "$B2_UPLOAD_SUCCESS" = "skipped" ]; then
NOTIFICATION_MESSAGE="${NOTIFICATION_MESSAGE}
💾 Local backup only (B2 upload skipped)"
send_notification "✅ Immich Backup Completed (Local Only)" "$NOTIFICATION_MESSAGE" "success"
elif [ "$B2_UPLOAD_SUCCESS" = true ] && [ -n "$B2_BUCKET_NAME" ]; then
NOTIFICATION_MESSAGE="${NOTIFICATION_MESSAGE}
☁️ Successfully uploaded to B2 bucket: ${B2_BUCKET_NAME}"
send_notification "✅ Immich Backup Completed" "$NOTIFICATION_MESSAGE" "success"