#!/usr/bin/env bash # # Install Immich on TrueNAS with GPU acceleration, and migrate a library without losing faces or albums # https://www.zadran.net/guides/immich-on-truenas-gpu-and-migration # Generated from the guide, last updated 2026-09-13. # # NO WARRANTY. This script is provided as is. You are responsible for # understanding what it does before running it, and for the consequences. # Take a backup first. See https://www.zadran.net/disclaimer # # Destructive steps are left commented out on purpose -- uncomment them # only once you have understood what they do. set -euo pipefail # ---- Set these for your environment ---- # ZFS pool for the database and model cache NVME_POOL='nvme' # ZFS pool for the photo library HDD_POOL='tank' # Where the NVMe pool is mounted NVME_POOL_PATH='/mnt/nvme' # Where the HDD pool is mounted HDD_POOL_PATH='/mnt/tank' # Existing photos to index in place, if any EXTERNAL_PHOTOS='/mnt/tank/Home/Photos' # Pin it; do not run release IMMICH_VERSION='v3.1.0' # Affects job schedules and timestamps TIMEZONE='Etc/UTC' # Only used when migrating from another machine OLD_HOST='old-nas.example.lan' zfs create -p ${NVME_POOL}/databases/immich zfs create -p ${NVME_POOL}/apps/immich/model-cache zfs create -p ${HDD_POOL}/Immich mkdir -p ${NVME_POOL_PATH}/apps/immich cd ${NVME_POOL_PATH}/apps/immich cat > .env <<'EOF' # Where the photo library lives - bulk storage UPLOAD_LOCATION=${HDD_POOL_PATH}/Immich # Where the Postgres data directory lives - fast storage DB_DATA_LOCATION=${NVME_POOL_PATH}/databases/immich # Pin the version. Never run :release in production and wonder why it changed. IMMICH_VERSION=${IMMICH_VERSION} TZ=${TIMEZONE} DB_PASSWORD=CHANGEME DB_USERNAME=postgres DB_DATABASE_NAME=immich EOF cd ${NVME_POOL_PATH}/apps/immich grep -A 8 'openvino:' hwaccel.ml.yml docker exec immich_machine_learning ls -l /dev/dri docker logs immich_machine_learning 2>&1 | grep -i -E 'openvino|provider' | tail -5 ls -la ${HDD_POOL_PATH}/Immich/backups/ # !! DESTRUCTIVE -- review, then uncomment to run: # docker compose down # rsync -aHAX --info=progress2 \ # ${OLD_HOST}:/path/to/old/postgres/data/ \ # ${NVME_POOL_PATH}/databases/immich/ ls -la ${HDD_POOL_PATH}/Immich/backups/ | tail -5 zfs list -o name | grep -i immich