3 min read

Backup Immich to Backblaze B2 Storage

Backup Immich to Backblaze B2 Storage
Photo by Soragrit Wongsa / Unsplash

If you're leveraging Immich—the self-hosted photo and video backup solution—you've taken a step toward owning your data (on-premises, no cloud storage). However, hosting your media solely on-premises, carries risks like hardware failure, fire, or theft. That's why implementing a robust backup strategy is essential. This post dives into the critical step of backing up your valuable Immich media library from its local on-premises storage to secure and scalable Backblaze B2 (S3-compatible block storage).

Installing and configuring rclone

Fist we need to install rclone, which will handle backing up the images to any compliant storage. In this post we are using Backblaze B2 block storage. I'm assuming you have already created a bucket and application key in Backblaze B2 control panel.

# Install rclone
> wget https://rclone.org/install.sh
> sudo bash install.sh

# Perform initial configuration of rclone
> rclone config

No remotes found, make a new one?
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n

Enter name for new remote.
name> Immich

Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.

 5 / Backblaze B2
   \ (b2)

Option account.
Account ID or Application Key ID.
Enter a value.
account> xxxxxxxx < Enter Key ID from Backblaze B2 portal

Option key.
Application Key.
Enter a value.
key> xxxxx < Enter application key from Backblaze B2 portal

Current remotes:

Name                 Type
====                 ====
Immich               b2

# Verify configuration settings
> rclone config show
[Immich]
type = b2
account = xxxxxx
key = xxxxxx

Now that the initial configuration of rclone has been performed. Let's do a test run.

# List all directories/containers/buckets in the path
> rclone lsd Immich:
 -1 2000-01-01 00:00:00        -1 ImmichBackup-Bucket

# List files in the bucket, in this case it is empty for now.
> rclone ls Immich:ImmichBackup-Bucket

Backing up the Immich database

We have configured rclone and the necessary bucket configurations. Now we will back up the Immich database. This is necessary for you to be able to restore Immich in case of an failure. The database contains necessary metadata and configurations, but not the media files.

# Create dump of the database (modify container names, usernames, directories as they are in your environment)
> docker exec -t immich_postgres pg_dumpall --clean --if-exists --username=postgres | gzip > "/immich/immich_dump.sql.gz"

# Backup database to Backblaze (-P for progress, not to be used with cron, use -q for quiet):
> rclone sync /immich/immich_dump.sql.gz Immich:ImmichBackup-Bucket -P
Transferred:       53.841 MiB / 53.841 MiB, 100%, 41.538 MiB/s, ETA 0s
Transferred:            1 / 1, 100%
Elapsed time:         1.5s

# Verify that the database backup has been uploaded
> rclone ls Immich:ImmichBackup-Bucket
 56456867 immich_dump.sql.gz

Backing up the Immich media library

In the previous step we backed up the Immich database. Next we will backup the whole media library.

# Backup the Immich media library (modify directories etc. as in your environment. I'm also excluding some files/directories I don't want backed up, in this case lost+found directory contents "--exclude "lost+found/**".
> rclone sync /immich/ Immich:ImmichBackup-Bucket -P --transfers 10 --fast-list --exclude "lost+found/**"
Transferred:       30.548 GiB / 57.438 GiB, 53%, 104.462 MiB/s, ETA 4m42s
Errors:                 0
Transferred:        12545 / 22563, 56%
Elapsed time:       5m9.5s
Transferring:
 * upload/e7b6e8e5-28dc-4…-9796-dd0ccd3a609b.MOV: 70% /77.981Mi, 29.183Mi/s, 0s
 * upload/e7b6e8e5-28dc-4…-8a92-c13fda8b864b.JPG: 69% /18.250Mi, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…23512f6-thumbnail.webp:100% /17.982Ki, 0/s, -
 * upload/e7b6e8e5-28dc-4…-ae2f-cfe0eb3d6804.jpg:100% /3.185Mi, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…b24e-a03f249c66b1.jpeg:100% /6.517Ki, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…c9cc885-thumbnail.webp:100% /18.006Ki, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…1cb4e5f5a-preview.jpeg:100% /209.963Ki, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…14be185bf-preview.jpeg:100% /69.520Ki, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…4e5373d-thumbnail.webp:100% /13.230Ki, 0/s, -
 * thumbs/e7b6e8e5-28dc-4…65dd204ed-preview.jpeg:100% /592.008Ki, 0/s, -

Now you have backed up the database and the Immich media library. Of course this has been a one time run, so let's look how to automate this by creating a cron job out of this.

Automating the backups using crontab

Automating the backups is as easy as implementing the above in a crontab.

# Edit the crontab
> crontab -e

# Add the commands (modified to your environment to the crontab and save). I also included some logging (--log-file) in the rclone part to log if backup runs into any issues
30 3 * * * docker exec -t immich_postgres pg_dumpall --clean --if-exists --username=postgres | gzip > "/immich/immich_dump.sql.gz"
50 3 * * * rclone sync /immich/ Immich:ImmichBackup-Bucket -q --transfers 10 --fast-list --exclude "lost+found/**" --log-file=/tmp/immich_bu_log.log

Conclusion

By following the steps outlined in this post, you've successfully elevated your personal media infrastructure, moving from a single point of failure to a highly resilient and durable system. Remember, a successful backup strategy isn't a one-time setup; it requires regular verification and testing. Now that your Immich library is safely mirrored off-site, you can rest assured knowing your library is securely protected for years to come.