Personal photo and video management systems like Immich house our most valuable digital assets, and the loss of this data can have serious consequences. In the event of a system crash, disk failure, or misconfiguration rendering Immich data inaccessible, a robust backup and restore strategy is vital. This guide explains step-by-step how to back up your Immich installation in accordance with 3-2-1 backup principles and how to restore it in the event of a disaster.
The 3-2-1 backup strategy recommends keeping three copies of your data on two different storage media, with one copy stored offsite. For Immich specifically, this requires protecting the database, uploaded media files, and configurations according to this principle. The process extends from taking consistent backups, moving them to different storage media, and most importantly, practicing restoration scenarios.
What is the Immich Data Structure and What are its Backup Components?
Immich is a self-hosted media server composed of various components; backing up each of these components is critically important. Fundamentally, Immich data is stored in a PostgreSQL database, a Redis instance, and media files on the file system. Additionally, configuration files necessary for the application to run are also items that need to be backed up.
The PostgreSQL database contains all photo and video metadata, user information, albums, tags, and other structural data. Redis is used for tasks such as the queue system for background jobs and short-lived caching; backing it up is generally not critical because Redis data can be easily recreated or the cache can be cleared. Media files are typically stored in the UPLOAD_LOCATION directory defined in the .env file and contain the actual photo and video content. Choosing the correct backup method for each of these components and ensuring consistency between backups is key to a successful restoration.
ℹ️ About Redis Data
Immich's Redis instance is typically used for temporary data and job queues. The loss of Redis data in a disaster scenario usually does not prevent the system from operating; however, pending background jobs may need to be restarted. Therefore, Redis backup is generally optional and not considered as critical as PostgreSQL and media files.
What Does the 3-2-1 Backup Strategy Mean for Immich?
The 3-2-1 backup strategy is considered the gold standard in data protection and is an excellent fit for personal media servers like Immich. This strategy protects your data against various risk factors and significantly increases your chances of recovery in the event of a potential disaster. When we apply this principle to Immich, a clear roadmap is drawn for how each component (database, media files, configuration) should be backed up.
The first "3" rule states that you should have at least three copies of your data: the primary data and two backup copies. For Immich, this means that in addition to the live data on your running server, you should have two separate backup copies. The second "2" rule emphasizes that you should store these copies on two different storage media. For example, you can keep one copy on a local disk (NAS or external HDD) and the other on a different medium such as cloud storage (an S3-compatible service, Backblaze B2). The final "1" rule states that at least one of the backup copies should be kept offsite. This ensures your data remains safe even in local disasters such as fire, flood, or theft.
⚠️ Diversity of Backup Media
Having different backup media prevents a single point of failure from affecting all your backups. For example, keeping all your backups on the same RAID array does not mean keeping them on a different medium; because RAID failure or data corruption can affect all copies. Physically separate disks or different cloud providers should be preferred.
You can easily implement the 3-2-1 strategy by using a local network-attached storage (NAS) unit and then a remote cloud storage service (e.g., an S3-compatible service or Backblaze B2). I have set up a similar structure for my Immich instances running on my own VPS; I take a local disk backup and then automatically synchronize it to a remote S3 bucket. This approach offers both fast local recovery and ensures my data remains safe even in the event of a regional disaster.
How to Back Up Immich Database (PostgreSQL)?
Backing up the Immich database is a critical step for consistency with media files. The most common and reliable method for backing up a PostgreSQL database is to use the pg_dump command. This command takes a logical backup of the database, and this backup can be easily restored to different PostgreSQL versions or different systems. The pg_dump command can create consistent backups even while the database is being used concurrently and does not block other users from accessing the database. However, especially for large databases and under high write loads, it is advisable to temporarily stop Immich services for absolute consistency.
Using compression during backup saves disk space. You can compress the pg_dump output with tools like gzip or bzip2. Also, it is good practice to use date and time information in the backup file name to distinguish different backups and easily clean up old ones. If you are running Immich with Docker Compose, you need to run pg_dump inside the PostgreSQL container using the docker exec command.
#!/bin/bash
# Backup directory
BACKUP_DIR="/path/to/your/immich_backups"
DB_NAME="immich"
DB_USER="immich"
# PostgreSQL container name (check from docker-compose.yml or with `docker ps`)
DB_CONTAINER="immich_postgres" # Default Immich Docker Compose container name
# Timestamp
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/immich_db_backup_${TIMESTAMP}.sql.gz"
echo "Starting Immich PostgreSQL database backup..."
# Run pg_dump in Docker Compose environment
# The -t flag is used to run the command without allocating a pseudo-TTY.
# The -U and -d flags specify the username and database name.
docker exec -t ${DB_CONTAINER} pg_dump -U ${DB_USER} -d ${DB_NAME} | gzip > ${BACKUP_FILE}
if [ $? -eq 0 ]; then
echo "Database backup completed successfully: ${BACKUP_FILE}"
else
echo "Error: Database backup failed."
exit 1
fi
# Clean up old backups (e.g., those older than 7 days)
find ${BACKUP_DIR} -name "immich_db_backup_*.sql.gz" -mtime +7 -delete
echo "Old database backups cleaned up."
This script saves Immich's PostgreSQL database as a compressed SQL file to the specified backup directory. Then, it automatically deletes backup files older than 7 days to prevent disk space from filling up. Running this script as a cron job at regular intervals is a good starting point for an automated backup process. Immich also creates automatic database backups in the UPLOAD_LOCATION/backups directory, and these backups can be managed from the web interface.
Backing Up and Synchronizing Immich Media Files
Backing up Immich media files is as critical as backing up the database, as the actual photo and video content is stored in these files. This folder, typically specified by the UPLOAD_LOCATION variable in Immich's .env file, contains all user-uploaded media. The most important point in backing up media files is to ensure consistency between the database backup and the file backup. Ideally, both backups should be taken within the same timeframe or at least brought to a consistent state through sequential operations.
Tools like rsync are highly effective for backing up media files. rsync optimizes backup time and disk/network usage by only copying changed or newly added files. This saves time and resources, especially for large media collections. You can run the rsync command by setting the backup directory to the directory where Immich stores its media files.
#!/bin/bash
# Backup directory
BACKUP_DIR="/path/to/your/immich_backups"
# Directory where Immich media files are located (e.g., the UPLOAD_LOCATION value in the .env file)
# This path is the mount point on the host machine in the Immich Docker Compose setup.
MEDIA_SOURCE_DIR="/path/to/your/immich_data/library" # Host-side equivalent of UPLOAD_LOCATION
MEDIA_BACKUP_TARGET="${BACKUP_DIR}/immich_media"
echo "Starting Immich media files backup..."
# Backup media files with rsync
# -a: archive mode (recursive, symlinks, permissions, times, group, owner)
# -v: verbose output
# --delete: delete files in the destination that are not in the source (for full synchronization)
# CAUTION: Can lead to data loss if used incorrectly, be careful!
# It is strongly recommended to check what will happen with the --dry-run flag first.
rsync -av --delete --dry-run ${MEDIA_SOURCE_DIR}/ ${MEDIA_BACKUP_TARGET}/
echo "The output above shows the changes that would be made with the --delete flag (dry-run)."
echo "Remove the --dry-run flag to apply the changes."
# For actual backup, remove the --dry-run flag:
# rsync -av --delete ${MEDIA_SOURCE_DIR}/ ${MEDIA_BACKUP_TARGET}/
if [ $? -eq 0 ]; then
echo "Media files backup completed successfully: ${MEDIA_BACKUP_TARGET}"
else
echo "Error: Media files backup failed."
exit 1
fi
echo "Immich media files backup process completed."
The script above synchronizes Immich's media files to the specified backup directory using rsync. The --delete flag ensures that files no longer present in the source directory are also deleted from the backup directory; this guarantees that the backup directory is exactly the same as the live system. However, extreme caution must be exercised when using this flag, as unintended data loss can occur if the wrong source directory is specified. It is important to run this script at the same time as or immediately after the database backup to ensure consistency.
💡 Stopping Immich Services Before Backup
When backing up both the database and media files, especially if the
--deleteflag is used, temporarily stopping Immich services is the safest approach. This prevents any files from being modified or deleted during the backup, ensuring a consistent snapshot. If you are using Docker Compose, you can stop services withdocker compose stopand restart them withdocker compose startafter the backup is complete.
Restoration Drill: Step-by-Step Immich Recovery Scenario
No matter how robust a backup strategy is, it is not fully reliable if the restoration process has not been tested. In a disaster, it can be difficult to take the correct steps under panic and stress; therefore, conducting regular restoration drills is critical. This section provides a practical scenario explaining step-by-step how to restore your Immich installation from a backup.
The restoration process consists of stopping Immich services, restoring the database, restoring media files, and restarting services. The order of these steps is important and must be followed carefully to prevent any inconsistencies. The restoration process is typically performed on a new server or over corrupted data on an existing server.
Step 1: Stop Immich Services
Before starting the restoration process, you need to stop all Immich-related services. This prevents any write operations to the database or media directory and ensures a consistent restoration environment.
cd /path/to/your/immich_installation # directory where docker-compose.yml is located
docker compose down #
Step 2: Restore PostgreSQL Database
To restore the database, we use the psql command. Deleting the existing database first and then restoring the backup is usually the cleanest method. Immich also offers database restoration via its web interface.
#!/bin/bash
# Restore directory and filename
BACKUP_FILE="/path/to/your/immich_backups/immich_db_backup_20260807100000.sql.gz" # Specify the backup file to be restored
DB_NAME="immich"
DB_USER="immich"
DB_CONTAINER="immich_postgres" # Default Immich Docker Compose container name
echo "Starting Immich PostgreSQL database restoration..."
# Delete and recreate the database inside the PostgreSQL container
# CAUTION: This command permanently deletes the existing database.
# Make sure your backup is sound!
docker exec -t ${DB_CONTAINER} dropdb -U ${DB_USER} ${DB_NAME}
docker exec -t ${DB_CONTAINER} createdb -U ${DB_USER} ${DB_NAME}
# Restore the backup file
gunzip -c ${BACKUP_FILE} | docker exec -i ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME}
if [ $? -eq 0 ]; then
echo "Database restoration completed successfully."
else
echo "Error: Database restoration failed."
exit 1
fi
Step 3: Restore Media Files
To restore media files, you can use commands like rsync or cp. If the target directory is empty, cp might suffice, but rsync is more flexible for overwriting existing files or copying only missing ones.
#!/bin/bash
# Location of backed-up media files
MEDIA_BACKUP_SOURCE="/path/to/your/immich_backups/immich_media"
# Target location for Immich media files (e.g., the UPLOAD_LOCATION value in the .env file)
MEDIA_TARGET_DIR="/path/to/your/immich_data/library" # Host-side equivalent of UPLOAD_LOCATION
echo "Starting Immich media files restoration..."
# Clean the target directory (optional, CAUTION: This command permanently deletes all data in the target directory!)
# rm -rf ${MEDIA_TARGET_DIR}/*
# Before running this command, ensure the target directory is correct and contains the data you want to delete.
# Restore media files
rsync -av ${MEDIA_BACKUP_SOURCE}/ ${MEDIA_TARGET_DIR}/
if [ $? -eq 0 ]; then
echo "Media files restoration completed successfully."
else
echo "Error: Media files restoration failed."
exit 1
fi
Step 4: Start Immich Services and Verify
After all data has been restored, restart Immich services.
cd /path/to/your/immich_installation
docker compose up -d #
Once the services have started, log into the Immich interface and check if your photos and videos are visible. Immich does not have a direct "library scan" feature for files manually restored to its primary media storage area, UPLOAD_LOCATION, because Immich does not monitor this directory for external changes. If there are inconsistencies between the database backup and the file system backup (e.g., files in the file system but not in the database), these files will not be recognized by Immich. In this case, you may need to re-upload these files to Immich, which could potentially lead to duplicate entries. For external libraries, the "Scan New Library Files" function can be triggered from the Immich interface.
Considerations During Immich Backup and Restore Process
Immich backup and restore processes require a careful approach as they deal with sensitive data. To increase the reliability of the process and prevent potential problems, it is necessary to pay special attention to some important points. These details will make your backup policies more robust and save you time in the event of a disaster.
First, consistency checks are vital. The timestamps or snapshots between the database backup and the media file backup should be as close as possible. If the database backup is very old and the media files are very new, you might have media that exists in the file system but not in the database, and Immich might not recognize them. In this case, since Immich does not have a direct "re-scan" function for its primary UPLOAD_LOCATION, you might need to re-upload these files to Immich. However, it is best for the system to be stable and relatively quiet at the time of backup.
🔥 Data Integrity and Consistency
Immich's database and media files are tightly coupled. Backing up only media files and neglecting the database, or vice versa, will lead to serious data integrity issues after restoration. A file not recorded in the database is non-existent to Immich.
Secondly, regular tests are indispensable. The only way to know if your backups truly work is to regularly try restoring them. These drills expose errors in your restoration scripts and help you detect unexpected problems in advance. It is safest to conduct tests in a test environment isolated from the production environment.
Thirdly, encryption for offsite backups is a critical security measure, especially for backups sent to the cloud or physically accessible external drives. Tools like gpg or rclone protect your data against unauthorized access by encrypting it. This ensures your data remains secure even in a compromised backup environment. I never skip this step when backing up some sensitive data from my own side projects.
Fourthly, monitoring backup jobs and setting up notification mechanisms are important. Learning in time that a backup job has failed reduces the risk of data loss. Sending cron job outputs via email or integrating with a notification service facilitates this monitoring process.
Finally, resource consumption and the capacity of the environment where Immich will run should be considered. Backup operations (especially rsync for large media libraries) can place a significant load on disk I/O and network bandwidth. This can affect the performance of live Immich services. Therefore, scheduling backup operations during off-peak hours or stopping Immich services during the backup period is a smart approach to maintain overall system performance. Additionally, you can prevent backup processes from overusing system resources by adjusting cgroup limits. Storing Immich's database on an SSD is recommended for performance.
Conclusion
While Immich offers a great platform for managing your personal media library, the security of your digital memories is your responsibility. The 3-2-1 backup strategy and step-by-step restoration drill covered in this guide are among the most effective ways to protect your Immich installation against potential disasters. Remember that backup is not just about copying data; it's also about regularly testing and verifying that these backups can be successfully restored.
Automating backup and restore processes, testing them regularly, and developing your strategy by considering possible scenarios will greatly reduce your data loss concerns. This effort you put into protecting your digital assets will save you invaluable peace of mind and time in a future crisis. The next step is to start implementing the steps in this guide for your own Immich installation and ensure your media library is secure.
Top comments (0)