Immich Immich

[SSO] Self-hosted photo and video backup and management platform

Immich is a high-performance self-hosted solution for backing up, organizing, and viewing photos and videos, with mobile clients, multi-user support, and local machine-learning search and recognition.

GPU acceleration intentionally disabled for Immich on this host.

Our host has an AMD Vega gfx90c iGPU. Immich’s ROCm/MIGraphX ML image causes GPU hangs and kernel resets that interrupt the desktop display. Immich issue #21648 documents gfx90c APU support being removed from current ROCm images: rocm unsupported on gfx90c APUs · Issue #21648 · immich-app/immich

GPU_COMPOSE_SUFFIX=amdgpu is shared by other services on this host, so retain this no-op override to keep Immich on CPU until upstream support is verified.

Nightly database exports and B2 snapshots are configured. Independent on-site recovery remains unfinished; confirm original-media coverage before relying on the backup setup for full library recovery.

References

Authentik

Immich uses native OIDC for Authentik’s media group. OAuth settings are persisted in Immich’s database and must be configured through its web administration interface. Keep an existing local Immich administrator and password login for recovery.

Host Configuration

Create config/docker/<host>/immich/authentik-client-secret with mode 0600. Set these values in ignored config/docker/<host>/.env.immich:

IMMICH_AUTHENTIK_CLIENT_ID=immich
IMMICH_AUTHENTIK_SIGNING_KEY=<asymmetric Authentik signing-key UUID>

Create the Authentik application:

scripts/authentik-apps.py --application immich --apply

Immich Settings

Sign in as the local administrator and set Administration > Settings > OAuth:

SettingValue
EnabledEnabled
Issuer URLhttps://sso.<domain>/application/o/immich/
Client IDimmich
Client secretIgnored host secret value
Token endpoint auth methodclient_secret_post
Scopeopenid email profile
ID token signing algorithmRS256
Userinfo signing algorithmnone
Storage label claimpreferred_username
Auto registerEnabled
Auto launchDisabled
Mobile Redirect URI Overridehttps://immich.<domain>/api/oauth/mobile-redirect

Leave role and quota claims unset so Authentik-created accounts remain ordinary Immich users.

Verify

Link an existing local account before making OIDC its normal login path. Test an authorized media member, a non-member, local-password recovery, browser logout, and mobile login/background uploads on every supported platform.

Backup

backup.yaml defines nightly PostgreSQL exports under ${DB_BACKUP_ROOT}/media-photo-immich/, covering the named-volume DB that Kopia’s bind source cannot read directly. Restore using matching PostgreSQL extensions/image, together with the photo library and external originals. See the backup guide for commands, coverage, retention and snapshot selection.

Recovery

  1. Recover database.dump, globals.sql and the manifest. Restore required roles and the Immich DB into a clean destination PostgreSQL named volume using compatible PostgreSQL/extensions and the matching application image. Keep Immich stopped until the database and media are ready.
  2. Recover ${DOCKER_VOLUMES}/immich/library, preserving .immich markers, and external originals from ${STORAGE_FAMILYMEDIA} at their original mount paths. Check their own snapshot coverage; the DB verifier does not inventory all originals or external mounts. Restore original credentials/OIDC configuration.
  3. Start the database and application, then validate original assets before regenerating missing thumbnails/encoded video.

Generated thumbs/encoded video and native immich-db-backup-*.sql.gz duplicates are excluded from B2; use our checked logical exports for DB recovery. Native SQL backups remain local. The named ML-model cache is not captured by the bind-source snapshot and can be re-downloaded when available.

Post-restore check

Start the matching PostgreSQL/extensions and app image with the restored library. Sign in, open one original photo and one video, and confirm albums/asset counts look reasonable. Verify one existing external-library path if used.

name: immich
services:
  immich-server:
    image: altran1502/immich-server:v3@sha256:485d546a2e31d6a8b4db8423fcba5c109de8c218d93410af115fd1ccfc4352a6
    container_name: immich-server
    restart: unless-stopped
    environment:
      TZ: ${TIMEZONE}
      DB_USERNAME: immich
      DB_PASSWORD: ${IMMICH_POSTGRES_PASSWORD}
      DB_DATABASE_NAME: immich
    volumes:
      - ${DOCKER_VOLUMES}/immich/library:/data
      - ${STORAGE_FAMILYMEDIA}:/external/family-media:ro
      # kics-scan ignore-line -- read-only timezone data, not a writable host directory.
      - /etc/localtime:/etc/localtime:ro
    depends_on:
      - redis
      - database
    networks:
      - proxy
      - immich
    labels:
      traefik.enable: true
      traefik.http.routers.immich.rule: Host(`immich.${MYDOMAIN}`)
      traefik.http.routers.immich.middlewares: localaccess@file
      traefik.http.services.immich.loadbalancer.server.port: 2283
      homepage.group: Media
      homepage.name: Immich
      homepage.icon: immich.png
      homepage.href: https://immich.${MYDOMAIN}/
      homepage.description: "[SSO] Self-hosted photo and video backup and management platform"

  immich-machine-learning:
    image: altran1502/immich-machine-learning:v3@sha256:5b28c9352c8374b8a1ed96fbdd8d6755fea6e43510ec43fdf6538aa02ea40f56
    container_name: immich-machine-learning
    restart: unless-stopped
    environment:
      TZ: ${TIMEZONE}
    volumes:
      - immich-model-cache:/cache
    networks:
      - immich

  redis:
    image: docker.io/valkey/valkey:9@sha256:418652cfb58ef879d4978c33553735d7147016032d5aefaa14c828e611eb9dfd
    container_name: immich-redis
    restart: unless-stopped
    healthcheck:
      test: redis-cli ping || exit 1
    networks:
      - immich

  database:
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23
    container_name: immich-postgres
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${IMMICH_POSTGRES_PASSWORD}
      POSTGRES_USER: immich
      POSTGRES_DB: immich
      POSTGRES_INITDB_ARGS: --data-checksums
    volumes:
      - immich-postgres:/var/lib/postgresql/data
    shm_size: 128mb
    healthcheck:
      disable: false
    networks:
      - immich

volumes:
  immich-model-cache:
  immich-postgres:

networks:
  proxy:
    external: true
  immich: