Immich Management Scripts
This directory contains scripts for managing and backing up Immich photo management system.
Scripts
backup-immich.sh
Complete backup script for Immich installation that creates backups of:
- PostgreSQL database (using pg_dumpall as recommended by Immich)
- User upload directories (photos, videos, and metadata)
Requirements:
.envfile in the parent directory (/home/acedanger/shell/.env) with:DB_USERNAME- PostgreSQL usernameDB_DATABASE_NAME- Database nameUPLOAD_LOCATION- Path to Immich upload directory
- Docker containers:
immich_postgresandimmich_server
Usage:
./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:
# 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:
Primary Storage: /mnt/share/media/backups/immich/ (shared storage)
- Database:
immich_db_backup_YYYYMMDD_HHMMSS.sql.gz - Uploads:
immich_uploads_YYYYMMDD_HHMMSS.tar.gz
Temporary Location: ../immich_backups/ (cleaned up after copy to shared storage)
Backup Workflow:
- Create local backups in temporary directory (
../immich_backups/) - Copy to shared storage (
/mnt/share/media/backups/immich/) - Upload to Backblaze B2 (if configured)
- Delete local copies (shared storage copies retained)
Features:
- Smart backup workflow: Creates → Copies to shared storage → Uploads to B2 → Cleans up locally
- 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
- Shared storage integration: Automatically copies backups to
/mnt/share/media/backups/immich/ - Local cleanup: Removes temporary files after successful copy to shared storage
- Automatic container pausing/resuming during backup
- Comprehensive error handling and cleanup
- Graceful degradation: Retains local backups if shared storage copy fails
- Backup validation and health checks
- Automatic compression
- Old backup cleanup (configurable)
- Centralized logging to
/home/acedanger/shell/logs/ - Detailed progress reporting and timestamped logs
- 🔔 Webhook notifications to notify.peterwood.rocks/lab
- ☁️ Backblaze B2 integration for off-site backup storage
- 📊 File size reporting in notifications
Usage Examples
Basic Operations
Standard Backup (Default)
./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
./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)
./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:
=== 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
Workflow:
1. Create local backups
2. Copy to shared storage: /mnt/share/media/backups/immich/
3. Upload to B2 (if configured)
4. Delete local backups (keep shared copies)
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
Shared Storage Check:
✓ Shared storage accessible: /mnt/share/media/backups
✓ Shared storage writable - would copy backups before B2 upload
=== DRY RUN COMPLETE - No files were created or modified ===
Local Backup Only
Skip B2 Upload
./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
./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
./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
./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)
# 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
#!/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
# 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
# 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
# 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:
# Database configuration
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
UPLOAD_LOCATION=/path/to/immich/uploads
# Notification settings
WEBHOOK_URL="https://notify.peterwood.rocks/lab"
# Backblaze B2 settings (optional)
# Get these from your B2 account: https://secure.backblaze.com/app_keys.htm
# B2_APPLICATION_KEY_ID=your_key_id_here
# B2_APPLICATION_KEY=your_application_key_here
# B2_BUCKET_NAME=your_bucket_name_here
# Optional: Backup retention (days)
BACKUP_RETENTION_DAYS=30
Shared Storage Configuration
The backup script automatically uses shared storage at /mnt/share/media/backups/immich/ for permanent backup storage. This provides:
- Centralized storage: All backups stored in one accessible location
- Network accessibility: Backups available across your network
- Space efficiency: Temporary local files are cleaned up after copying
Requirements:
/mnt/share/media/backups/directory must be accessible and writable- Sufficient disk space for backup files (database + uploads archive)
Fallback behavior:
- If shared storage is inaccessible, backups remain in local temporary directory
- Script logs warnings but continues operation
- B2 upload still functions from local files if configured
Backup Strategy
Workflow Process:
- Local Creation: Backups created in temporary directory (
../immich_backups/) - Shared Storage Copy: Files copied to
/mnt/share/media/backups/immich/ - B2 Upload: Local files uploaded to Backblaze B2 (if configured)
- Local Cleanup: Temporary files deleted after successful copy to shared storage
Backup Content (based on Immich's official recommendations):
-
Database Backup: Uses
pg_dumpallwith--cleanand--if-existsflags -
Upload Directory: Complete archive of upload location including:
- upload/ - Original photos and videos
- profile/ - User profile images
- thumbs/ - Generated thumbnails
- encoded-video/ - Transcoded videos
- library/ - Library metadata
- backups/ - Existing backup files (excluded from new backups)
Safety Features:
- Graceful degradation: If shared storage fails, keeps local backups
- Error isolation: B2 upload failure doesn't affect local or shared storage
- Container safety: Immich server paused during backup to ensure consistency
Notifications 🔔
The backup script sends notifications to your webhook URL with:
- 🚀 Start notification: When backup begins
- ✅ Success notification: When backup completes successfully with file sizes
- ⚠️ Warning notification: When backup succeeds but B2 upload fails
- 🚨 Error notification: When backup fails
Example notification:
📦 Database: immich_db_backup_20250526_215913.sql.gz (150MB)
📁 Uploads: immich_uploads_20250526_215913.tar.gz (25GB)
💾 Stored in: /mnt/share/media/backups/immich (local files cleaned up)
☁️ Successfully uploaded to B2 bucket: my-immich-backups
Backblaze B2 Integration ☁️
Setup B2 Account
- Create a Backblaze B2 account
- Create a new bucket for Immich backups
- Generate application keys:
- Go to: https://secure.backblaze.com/app_keys.htm
- Create new key with read/write access to your bucket
Configure B2 in .env
Add these variables to your .env file:
B2_APPLICATION_KEY_ID=your_key_id_here
B2_APPLICATION_KEY=your_application_key_here
B2_BUCKET_NAME=your_bucket_name_here
B2 Features
- Automatic upload: Backup files are uploaded to B2 after creation
- Organized storage: Files stored in
immich-backups/folder in your bucket - Error handling: Script continues if B2 upload fails (local backup preserved)
- Progress tracking: Upload status included in notifications
The B2 CLI tool (b2-linux) is included in this directory and doesn't require separate installation.
Restore Process
For complete restore instructions, see: https://immich.app/docs/administration/backup-and-restore/
Backup File Locations:
- Primary:
/mnt/share/media/backups/immich/(shared storage) - Fallback:
../immich_backups/(if shared storage copy failed) - Cloud: Backblaze B2 bucket (if B2 upload was configured)
Restore Steps:
-
Database Restore:
# From shared storage (primary location) docker exec -i immich_postgres psql -U postgres < /mnt/share/media/backups/immich/immich_db_backup_YYYYMMDD_HHMMSS.sql # OR from B2 download ./b2-linux download-file-by-name your-bucket immich-backups/immich_db_backup_YYYYMMDD_HHMMSS.sql.gz gunzip immich_db_backup_YYYYMMDD_HHMMSS.sql.gz docker exec -i immich_postgres psql -U postgres < immich_db_backup_YYYYMMDD_HHMMSS.sql -
Upload Directory Restore:
# From shared storage (primary location) tar -xzf /mnt/share/media/backups/immich/immich_uploads_YYYYMMDD_HHMMSS.tar.gz -C /target/location # OR from B2 download ./b2-linux download-file-by-name your-bucket immich-backups/immich_uploads_YYYYMMDD_HHMMSS.tar.gz tar -xzf immich_uploads_YYYYMMDD_HHMMSS.tar.gz -C /target/location
Logs
Backup logs and performance metrics are stored in the main shell logs directory (/home/acedanger/shell/logs/).
Monitoring
The backup script includes:
- Progress indicators for long-running operations
- Size validation for backup files
- Container status monitoring
- Automatic cleanup procedures
- Comprehensive error reporting
Automation
To automate backups, add to crontab:
# Daily Immich backup at 2:00 AM
0 2 * * * /home/acedanger/shell/immich/backup-immich.sh >> /home/acedanger/shell/logs/immich-backup.log 2>&1