Skip to content

Immich -- Setup

High-performance self-hosted photo and video management solution with AI-powered search, facial recognition, and automatic mobile backup. Runs as a Docker Compose stack on a dedicated Debian LXC (127). OIDC via PocketID, media stored on urahara.

  • GitHub: https://github.com/immich-app/immich
  • Website: https://immich.app
  • Docs: https://immich.app/docs/overview/introduction
  • API Docs: https://immich.app/docs/api

Infrastructure

Host LXC ID Internal External CPU RAM Disk
Debian LXC 127 192.168.1.127:2283 https://photos.eva-00.network 4 cores 8 GiB 32 GiB

Observability

Logs

Container logs are collected via Docker log driver. Query in Loki:

Query Purpose
{container_name="immich_server"} Immich server logs
{container_name="immich_machine_learning"} ML model inference logs
{container_name="immich_postgres"} PostgreSQL database logs
{container_name="immich_redis"} Redis/Valkey cache logs
{container_name=~"immich.*"} \|= "error" All errors

Access: Grafana > Explore > Loki > Enter query

IaC

Artifact Path
Playbook ansible/playbooks/immich.yml
Workflow .forgejo/workflows/immich.yml
Docker Compose services/immich/docker-compose.yml
Theme CSS services/immich/apple-theme.css
Caddy entry services/caddy/Caddyfile > photos.eva-00.network
Glance entry services/glance/glance.yml > Media section + Immich widget

The playbook manages the full lifecycle:

  1. Provisions LXC 127 on Proxmox (via create-lxc.yml)
  2. Resizes LXC to 8GB RAM / 4 cores (workflow step)
  3. Installs Docker
  4. Fetches secrets from Vault
  5. Deploys Docker Compose stack (server + ML + PostgreSQL + Redis)
  6. Creates holo admin user via initial signup API
  7. Configures OIDC (PocketID) via system config API
  8. Applies Apple Photos-inspired custom CSS theme
  9. Disables password login
  10. Generates API key and stores it in Vault
  11. Deploys Alloy observability agent

Auth

Component Details
OIDC Provider PocketID (auth.eva-00.network)
Callback URL https://photos.eva-00.network/auth/login
Mobile Redirect app.immich:///oauth-callback (custom URL scheme for iOS/Android app OIDC)
Auth mode OIDC-only (password login disabled after first-run)
Auto-register Enabled -- new PocketID users auto-create Immich accounts

Secrets

Vault path: secret/data/immich

Key Purpose
admin_email Admin account email (holo)
admin_password Admin account password (used for initial signup only)
db_password PostgreSQL database password
pocketid_client_id OIDC client ID
pocketid_client_secret OIDC client secret
api_key REST API key (generated on first run)

AI / Machine Learning

Immich includes a built-in machine learning service for:

  • Smart Search (CLIP): Search photos by description ("sunset at the beach") without tags
  • Facial Recognition: Detects and clusters faces across your library
  • Duplicate Detection: Identifies duplicate/similar photos
  • OCR: Extracts text from images for searchability

All ML runs CPU-only on LXC 127 (no GPU passthrough). Initial model downloads are ~2GB. First-time processing of a large library is slow but subsequent processing is fast.

Setting Value
ML Image ghcr.io/immich-app/immich-machine-learning:release
Model Cache /opt/immich/model-cache (inside LXC)
Inference CPU-only

Containers

Container Image Purpose
immich_server ghcr.io/immich-app/immich-server:release Web app + API + microservices
immich_machine_learning ghcr.io/immich-app/immich-machine-learning:release ML inference (CLIP, face detection)
immich_postgres ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0 PostgreSQL + pgvecto.rs vector search
immich_redis docker.io/valkey/valkey:9-alpine Job queue and caching

Storage

Path Mount Purpose
/opt/immich/database Bind mount (LXC rootfs) PostgreSQL data
/opt/immich/model-cache Bind mount (LXC rootfs) ML model cache (~2GB)
/mnt/immich/upload Proxmox bind mount from urahara All uploaded photos/videos

The actual media lives on urahara (/mnt/pve/urahara/immich) and is bind-mounted into the LXC at /mnt/immich/upload. This separates media storage from the LXC rootfs.

Backup Strategy

Database (PostgreSQL)

  • Databasement: Daily 2:00 AM pg_dump via SSH tunnel to cajita-elite
  • Backrest: Snapshot of Databasement dumps at 2:30 AM
  • PBS: LXC 127 snapshot (nightly, non-critical schedule -- Monday 4:00 AM)

Media (photos/videos on urahara)

  • Backrest: Add /mnt/pve/urahara/immich as a backup source on chizuru
  • senku: Included via PBS snapshot sync when plugged in

What to back up

Data Location Method Priority
PostgreSQL DB /opt/immich/database Databasement + PBS Critical
Uploaded media /mnt/pve/urahara/immich Backrest + senku Critical
ML model cache /opt/immich/model-cache Not backed up (re-downloaded) Low

Client Apps

Platform App Notes
iOS/iPadOS Immich (official) Auto-backup, Live Photos, OIDC login
macOS Immich (official) Native macOS app
Android Immich Auto-backup, OIDC login
Web https://photos.eva-00.network Full-featured web UI
CLI immich-cli Bulk upload tool

Users

User Role Access
holo Admin Full admin, created via initial signup
milton User Auto-created on first PocketID OIDC login