Normal installation, not through Portainer, but via cli, since to run immich instance, we need to run multiple Docker containers.

Migration to the SSD from HDD of database. Since database is a frequent read-write load, HDD are not suitable for this. It is highly recommended to use the SSD to store the db file. It is a simple process of moving the db file form the HDD to SDD location and changing the file path in .env file for database.

Now about the backup of .db file. Taking a live backup through rsync function for the database won’t work, since it will almost always result in broken db and hence not useful. There is a different method recommended.

I have changed the location of the db from HDD to my docker-data folder in SSD /srv/docker-data/immich/immich-pgdata I have also changed the location of the database folder in /srv/docker-data/immich/.env

Ran the docker again and everything was fine.

Now a new script is required that will take make a backable copy of the database /srv/docker-data/immich/backup_db.sh

#!/bin/bash
 
# --- Configuration ---
LOG_FILE="/var/log/server_backup.log"
DUMP_DIR="/srv/docker-data/database-dumps"
IMMICH_DIR="/srv/docker-data/immich"
DB_CONTAINER="immich_postgres"
DB_USER="postgres"
 
# --- Functions ---
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | sudo tee -a ${LOG_FILE}
}
 
# --- Main Script ---
log_message "--- Starting Immich DB Dump ---"
 
# Create the dump directory using sudo (if it doesn't exist)
log_message "Ensuring database dump directory exists at ${DUMP_DIR}"
sudo mkdir -p ${DUMP_DIR}
 
# Navigate to the Immich compose directory
cd ${IMMICH_DIR} || { log_message "ERROR: Failed to cd to ${IMMICH_DIR}"; exit 1; }
 
# Run the dump, capture all output, and log it
{
    log_message "Starting pg_dumpall..."
    docker exec -t ${DB_CONTAINER} pg_dumpall --clean --if-exists --username=${DB_USER} | gzip | sudo tee ${DUMP_DIR}/immich_db.sql.gz > /dev/null
 
    # Check the status of the docker exec command, not tee
    if [ ${PIPESTATUS[0]} -eq 0 ]; then
       log_message "Successfully created database dump at ${DUMP_DIR}/immich_db.sql.gz"
    else
       log_message "ERROR: Database dump failed! (Check docker logs for ${DB_CONTAINER})"
    fi
} 2>&1 | sudo tee -a ${LOG_FILE}
 
log_message "--- Finished Immich DB Dump ---"
exit 0

This scripts run the command pg_dumpall which creates a backable copy of the postgres database. This will run before the nightly backup and create a file immich_db.sql.gz in /srv/docker-data/database-dumps. And since the folder is scheduled to be backed up with rsync, it will automatically backup the database dump.

chmod +x /srv/docker-data/immich/backup_db.sh # To make the file executable

Another thing to do is the stop the original db folder syncing with the backup so we explicitly forbid the folder to be removed form sync by adding the command with flad --exclude in the original backup.sh. Read more at Backup.

sudo rsync -a --delete --exclude 'immich-pgdata/' "${BACKUP_SRC_CONFIG}" "${BACKUP_DEST_CONFIG}"

Then we can add these two scripts to run every night through nvim crontab -e and adding these lines there:

# Run the database dump at 2:55 AM
55 2 * * * /srv/docker-data/immich/backup_db.sh
 
# Run the main file backup at 3:00 AM
0 3 * * * /path/to/simple_backup_script.sh

This should solve all the issues. We can see the backup log at /var/log/server_backup.log

Now restoration process is also a bit different compared to the other mentioned in Backup note.

Here is the step-by-step guide to restore your Immich database from the backup you created.

This process is destructive, meaning it will wipe out the current database before restoring the old one. Only do this if you are sure you need to revert to a backup.

Important: File Paths We Will Use

  • Immich Directory: /srv/docker-data/immich (where your docker-compose.yml is)

  • Database Backup File: /srv/docker-data/database-dumps/immich_db.sql.gz (the file our script creates)

  • Database Data Location: /srv/docker-data/immich-pgdata/database (the new SSD location)

  • DB Container Name: immich_postgres (default)

  • DB Username: postgres (default)


Step-by-Step Restore Guide

  1. Navigate to your Immich Directory All docker compose commands must be run from here.

    Bash

    cd /srv/docker-data/immich
    
  2. Shut Down and Completely Remove Immich This command stops and deletes all Immich containers, networks, and anonymous volumes.

    Bash

    docker compose down
    
  3. WIPE the Current Database Files This is the most critical step to prevent conflicts. You must start with an empty database directory.

    Bash

    sudo rm -rf /srv/docker-data/immich/immich-pgdata/database
    

    (Don’t worry, your docker-compose.yml will re-create the parent folder structure when it starts).

  4. Re-create the Containers This reads your docker-compose.yml and creates the containers (but doesn’t start them). If you also want to update Immich, run docker compose pull before this.

    Bash

    docker compose create
    
  5. Start ONLY the Database Container We need the database running by itself so we can load the backup into it.

    Bash

    docker start immich_postgres
    
  6. Wait for the Database to Initialize Give Postgres ~10-15 seconds to start up fully.

    Bash

    sleep 15
    
  7. Run the Restore Command This is the one-liner that does all the work. It unzips your backup file, pipes the SQL data, and executes it inside the immich_postgres container.

    Bash

    sudo gunzip --stdout /srv/docker-data/database-dumps/immich_db.sql.gz | docker exec -i immich_postgres psql --username=postgres --dbname=postgres
    
    • sudo gunzip ...: We need sudo to read the root-owned backup file.

    • psql --username=postgres --dbname=postgres: We pipe the data into the psql command, telling it to connect as the user postgres to the default postgres database (the pg_dumpall backup will handle creating the specific immich database inside).

  8. Start the Rest of Immich Once the command in step 7 is finished, you can start the full Immich stack.

    Bash

    docker compose up -d
    

That’s it! Open your Immich web UI. Your instance should be fully restored to the state it was in when the backup was taken.