Backup & DR
Consolidated backup and restore reference. Service-specific pages contain fuller context - this page covers the overall DR order and quick-reference commands for each critical data store.
Recovery order
Section titled “Recovery order”If the homelab needs to be rebuilt from scratch, restore in this sequence.
Step 1. VPS first. Keycloak and Pangolin must be online before any service that depends on OIDC authentication. Without Keycloak, no service can authenticate users. Without Pangolin, external access to Immich, Jellyfin, OpenCloud, and Planka is severed.
Step 2. TrueNAS pool. Import the tank pool. All service data lives under tank/apps/ and tank/configs/. Datasets are unencrypted.
Step 3. Services. Restore in any order after the pool is online. Each service mounts its own dataset path and is independent of the others.
Keycloak
Section titled “Keycloak”Runs on the VPS at /opt/keycloak/. Back up before any Keycloak version upgrade.
# Backup - PostgreSQL dumpdocker exec keycloak-postgres pg_dump -U keycloak keycloak \ > /opt/keycloak/backup-$(date +%Y%m%d).sql
# Restoredocker exec -i keycloak-postgres psql -U keycloak keycloak \ < /opt/keycloak/backup-YYYYMMDD.sqlStart keycloak-postgres first, restore, then start keycloak. Verify the OIDC discovery endpoint responds before bringing up dependent services.
curl -s https://auth.wighttrash.uk/realms/wighttrash/.well-known/openid-configurationSee Keycloak for upgrading and the break-glass kcadmin account.
Immich
Section titled “Immich”All data lives on TrueNAS. Two datasets to preserve:
| Dataset | Contents |
|---|---|
tank/apps/immich/data | Photo and video library |
tank/apps/immich/pgData | PostgreSQL database (pgvecto) |
The photo library is the critical backup target. If pgData is lost but data is intact, Immich can rescan and rebuild the database (albums, faces, and memories are lost but files are not).
# Backup databasesudo docker exec ix-immich-pgvecto-1 pg_dump -U immich immich \ > /mnt/tank/configs/immich-backup-$(date +%Y%m%d).sql
# Restore databasecat /mnt/tank/configs/immich-backup-YYYYMMDD.sql | \ sudo docker exec -i ix-immich-pgvecto-1 psql -U immich immichDatabase user: immich. Database name: immich. Container: ix-immich-pgvecto-1. See Immich for the OAuth recovery procedure.
Planka
Section titled “Planka”Data lives at /mnt/tank/configs/planka/. Two components: PostgreSQL database and uploaded file attachments.
# Backup databasedocker exec planka-db pg_dump -U planka planka \ > /mnt/tank/configs/planka/backup-$(date +%Y%m%d).sql
# Backup file attachmentstar czf /mnt/tank/configs/planka/attachments-backup-$(date +%Y%m%d).tar.gz \ -C /mnt/tank/configs/planka attachments user-avatars background-images favicons
# Restore databasedocker stop plankacat /mnt/tank/configs/planka/backup-YYYYMMDD.sql | \ docker exec -i planka-db psql -U planka planka
# Restore filestar xzf /mnt/tank/configs/planka/attachments-backup-YYYYMMDD.tar.gz \ -C /mnt/tank/configs/planka
# Fix permissions and restartchown -R 1000:1000 /mnt/tank/configs/planka/{favicons,user-avatars,background-images,attachments}docker start plankaSee Planka for the full install and database restore procedure.
OpenCloud
Section titled “OpenCloud”Data lives at /mnt/tank/configs/opencloud/. Two directories:
| Path | Contents |
|---|---|
/mnt/tank/configs/opencloud/data | User files and OpenCloud metadata |
/mnt/tank/configs/opencloud/config | Configuration including csp.yaml |
# Backup config directorytar czf /mnt/tank/opencloud-config-backup-$(date +%Y%m%d).tar.gz \ /mnt/tank/configs/opencloud/config
# ZFS snapshot of the full data directory (preferred for consistency)zfs snapshot tank/configs/opencloud@$(date +%Y%m%d)
# List snapshotszfs list -t snapshot | grep opencloud
# Roll back to a snapshotzfs rollback tank/configs/opencloud@YYYYMMDDSee OpenCloud for restart commands and Keycloak role requirements.
TrueNAS pool
Section titled “TrueNAS pool”The tank pool is RAIDZ1 across 3 drives. One drive failure is tolerated. Datasets are unencrypted.
# Pool statuszpool status tank
# Manual scrub (scheduled automatically every Sunday at 00:00)zpool scrub tank
# Export pool (before physical move to new hardware)zpool export tank
# Import pool (on new hardware)zpool import tankMonitor pool status in TrueNAS Storage - Pools for any errors or degraded state. A degraded pool still functions but has no redundancy - replace failed drives promptly.