mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 05:40:11 -08:00
feat: Add bash completion for backup scripts and enhance README documentation
This commit is contained in:
219
immich/README.md
219
immich/README.md
@@ -22,7 +22,36 @@ Complete backup script for Immich installation that creates backups of:
|
||||
**Usage:**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh [OPTIONS]
|
||||
```
|
||||
|
||||
**Command-Line Options:**
|
||||
|
||||
- `--help, -h` - Show 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
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Standard backup (default behavior)
|
||||
./backup-immich.sh
|
||||
|
||||
# Show help and usage information
|
||||
./backup-immich.sh --help
|
||||
|
||||
# Preview what would be backed up without executing
|
||||
./backup-immich.sh --dry-run
|
||||
|
||||
# Backup locally only (skip B2 upload)
|
||||
./backup-immich.sh --no-upload
|
||||
|
||||
# Run with verbose logging
|
||||
./backup-immich.sh --verbose
|
||||
|
||||
# Combine options
|
||||
./backup-immich.sh --no-upload --verbose
|
||||
```
|
||||
|
||||
**Backup Location:**
|
||||
@@ -32,6 +61,9 @@ Complete backup script for Immich installation that creates backups of:
|
||||
|
||||
**Features:**
|
||||
|
||||
- Command-line options for flexible operation (--help, --dry-run, --no-upload, --verbose)
|
||||
- Dry-run mode to preview operations without executing
|
||||
- Option to skip B2 upload for local-only backups
|
||||
- Automatic container pausing/resuming during backup
|
||||
- Comprehensive error handling and cleanup
|
||||
- Backup validation and health checks
|
||||
@@ -43,6 +75,191 @@ Complete backup script for Immich installation that creates backups of:
|
||||
- ☁️ **Backblaze B2 integration** for off-site backup storage
|
||||
- 📊 **File size reporting** in notifications
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Operations
|
||||
|
||||
**Standard Backup (Default)**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh
|
||||
# Performs complete backup with all default settings:
|
||||
# - Backs up database and upload directory
|
||||
# - Uploads to B2 if configured
|
||||
# - Sends webhook notifications
|
||||
# - Logs to /home/acedanger/shell/logs/immich-backup.log
|
||||
```
|
||||
|
||||
**Getting Help**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh --help
|
||||
# Shows complete usage information including:
|
||||
# - All available command-line options
|
||||
# - Configuration requirements
|
||||
# - Examples and restore instructions
|
||||
```
|
||||
|
||||
### Preview and Testing
|
||||
|
||||
**Dry Run (Preview Mode)**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh --dry-run
|
||||
# Shows what would be backed up without executing:
|
||||
# - Checks all prerequisites and container status
|
||||
# - Displays backup file paths and estimated sizes
|
||||
# - Validates B2 configuration if present
|
||||
# - Reports any issues that would prevent backup
|
||||
# - No files are created or modified
|
||||
```
|
||||
|
||||
Example dry-run output:
|
||||
|
||||
```text
|
||||
=== DRY RUN MODE - NO ACTUAL BACKUP WILL BE PERFORMED ===
|
||||
|
||||
Configuration:
|
||||
- Database: immich
|
||||
- Username: postgres
|
||||
- Upload Location: /opt/immich/upload
|
||||
- Container: immich_postgres
|
||||
- Backup Directory: /home/acedanger/shell/immich_backups
|
||||
|
||||
Would create:
|
||||
- Database backup: /home/acedanger/shell/immich_backups/immich_db_backup_20250527_140000.sql.gz
|
||||
- Upload backup: /home/acedanger/shell/immich_backups/immich_uploads_20250527_140000.tar.gz
|
||||
|
||||
Container Status Check:
|
||||
✓ immich_server: Running (would pause during backup)
|
||||
✓ immich_postgres: Running
|
||||
✓ Upload directory: /opt/immich/upload (42GB)
|
||||
|
||||
B2 Upload Configuration:
|
||||
✓ B2 configured - would upload to bucket: my-immich-backups
|
||||
✓ B2 CLI found at: /home/acedanger/shell/immich/b2-linux
|
||||
|
||||
=== DRY RUN COMPLETE - No files were created or modified ===
|
||||
```
|
||||
|
||||
### Local Backup Only
|
||||
|
||||
**Skip B2 Upload**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh --no-upload
|
||||
# Performs backup but skips B2 upload:
|
||||
# - Creates local backup files
|
||||
# - Validates backup integrity
|
||||
# - Sends notifications (without B2 status)
|
||||
# - Useful for testing or when B2 is unavailable
|
||||
```
|
||||
|
||||
### Verbose Logging
|
||||
|
||||
**Detailed Output**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh --verbose
|
||||
# Enables detailed logging for troubleshooting:
|
||||
# - Shows additional progress information
|
||||
# - Includes Docker command output
|
||||
# - Provides more detailed error messages
|
||||
# - Helpful for debugging issues
|
||||
```
|
||||
|
||||
### Combined Options
|
||||
|
||||
**Local Backup with Verbose Output**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh --no-upload --verbose
|
||||
# Combines multiple options:
|
||||
# - Creates local backup only (no B2 upload)
|
||||
# - Shows detailed progress and logging
|
||||
# - Useful for testing or troubleshooting
|
||||
```
|
||||
|
||||
**Preview with Verbose Details**
|
||||
|
||||
```bash
|
||||
./backup-immich.sh --dry-run --verbose
|
||||
# Shows detailed preview information:
|
||||
# - Extended configuration validation
|
||||
# - More detailed container status
|
||||
# - Comprehensive B2 configuration check
|
||||
# - Additional filesystem checks
|
||||
```
|
||||
|
||||
### Automation Examples
|
||||
|
||||
**Scheduled Backup (Crontab)**
|
||||
|
||||
```bash
|
||||
# Daily backup at 2:00 AM with logging
|
||||
0 2 * * * /home/acedanger/shell/immich/backup-immich.sh >> /home/acedanger/shell/logs/immich-backup.log 2>&1
|
||||
|
||||
# Weekly local-only backup (no B2 upload) at 3:00 AM on Sundays
|
||||
0 3 * * 0 /home/acedanger/shell/immich/backup-immich.sh --no-upload
|
||||
|
||||
# Daily validation run (dry-run) at 1:55 AM to check system health
|
||||
55 1 * * * /home/acedanger/shell/immich/backup-immich.sh --dry-run >> /home/acedanger/shell/logs/immich-validation.log 2>&1
|
||||
```
|
||||
|
||||
**Manual Backup Scripts**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# emergency-backup.sh - Quick local backup without B2
|
||||
echo "Starting emergency Immich backup..."
|
||||
/home/acedanger/shell/immich/backup-immich.sh --no-upload --verbose
|
||||
|
||||
#!/bin/bash
|
||||
# weekly-validation.sh - Comprehensive system check
|
||||
echo "Validating Immich backup system..."
|
||||
/home/acedanger/shell/immich/backup-immich.sh --dry-run --verbose
|
||||
```
|
||||
|
||||
### Troubleshooting Examples
|
||||
|
||||
**Check System Status**
|
||||
|
||||
```bash
|
||||
# Quick system validation without backup
|
||||
./backup-immich.sh --dry-run
|
||||
|
||||
# If containers are not running:
|
||||
docker ps | grep immich # Check container status
|
||||
docker start immich_server immich_postgres # Start if needed
|
||||
|
||||
# If upload directory missing:
|
||||
ls -la /opt/immich/upload # Verify path exists
|
||||
```
|
||||
|
||||
**Test B2 Configuration**
|
||||
|
||||
```bash
|
||||
# Backup without B2 to test local functionality
|
||||
./backup-immich.sh --no-upload
|
||||
|
||||
# Check B2 CLI manually
|
||||
./b2-linux version # Verify B2 CLI works
|
||||
./b2-linux authorize-account YOUR_KEY_ID YOUR_KEY # Test authorization
|
||||
```
|
||||
|
||||
**Debug Backup Issues**
|
||||
|
||||
```bash
|
||||
# Run with maximum detail for troubleshooting
|
||||
./backup-immich.sh --verbose --no-upload
|
||||
|
||||
# Check logs for errors
|
||||
tail -f /home/acedanger/shell/logs/immich-backup.log
|
||||
|
||||
# Validate backup files
|
||||
ls -la /home/acedanger/shell/immich_backups/
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The scripts expect a `.env` file in the parent directory with the following variables:
|
||||
@@ -90,7 +307,7 @@ The backup script sends notifications to your webhook URL with:
|
||||
|
||||
Example notification:
|
||||
|
||||
```
|
||||
```text
|
||||
📦 Database: immich_db_backup_20250526_215913.sql.gz (150MB)
|
||||
📁 Uploads: immich_uploads_20250526_215913.tar.gz (25GB)
|
||||
☁️ Successfully uploaded to B2 bucket: my-immich-backups
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user