Files
Main/2 Personal/Home Lab/NAS/immich_v1_setup.md
Obsidian-MBPM4 31e9ecf447 vault backup: 2026-03-31 12:52:27
Affected files:
2 Personal/Home Lab/NAS/immich_v1_setup.md
2026-03-31 12:52:27 +02:00

12 KiB

Immich V1 setup on Proxmox + Synology NAS + Authentik + Pangolin

Goal

Set up Immich first, on a full Linux VM in Proxmox (not Docker inside LXC), with:

  • media storage on a Synology NAS share
  • database on local VM storage
  • OIDC login via Authentik
  • public access through Pangolin
  • Synology snapshots enabled for the media share

This is the right V1 shape because Immich recommends Linux, Docker Compose, and a full VM when virtualized. It also explicitly says the Postgres database should ideally use local SSD storage and never a network share. The reverse proxy must forward the right headers, allow large uploads, and Immich must be served at the root of a domain/subdomain rather than a sub-path.
Sources: Immich Requirements, Reverse Proxy, OAuth Authentication.


flowchart LR
    subgraph Internet
        U[Users / Immich mobile app / browser]
    end

    subgraph Edge
        P[Pangolin\nTLS + public entrypoint]
    end

    subgraph Prod[Proxmox production]
        VM[Debian/Ubuntu VM\nDocker Compose\nImmich server + ML + Redis + Postgres]
        DB[(Postgres data\nlocal VM disk)]
        CFG[(Compose files/.env\nlocal VM disk)]
    end

    subgraph NAS[Synology NAS]
        NFS[NFS share for Immich upload library]
        SNAP[Synology snapshots]
        HB[Hyper Backup / offsite replication later]
    end

    subgraph IdP[Identity]
        AK[Authentik\nOIDC provider]
    end

    U --> P --> VM
    VM --> AK
    VM --> DB
    VM --> CFG
    VM --> NFS
    NFS --> SNAP
    SNAP --> HB

Hard recommendations

Do this

  1. Run Immich in a VM, not an LXC.
  2. Put Postgres on local VM storage.
  3. Put Immich upload/media storage on the NAS using a Unix-compatible mounted path.
  4. Use OIDC with Authentik, but keep local password login enabled until OIDC works.
  5. Publish Immich on its own subdomain, for example immich.example.com.
  6. Use a dedicated Synology shared folder for Immich media.
  7. Turn on Btrfs snapshots on that shared folder.

Do not do this

  1. Do not put DB_DATA_LOCATION on the NAS.
  2. Do not serve Immich on a sub-path like https://example.com/immich.
  3. Do not expose port 2283 directly to the internet.
  4. Do not use the NAS share for everything. Only media belongs there; DB does not.

Best-practice V1 decision: primary upload storage vs external library

For a fresh setup, use the NAS-mounted path as Immich's main UPLOAD_LOCATION.

Use External Libraries only if you already have existing folders on the NAS that Immich should index without owning. External libraries need the directory mounted into the container too, and tcby adding additional volume mounts.
Source: Immich External Library guide.

So for V1:

  • UPLOAD_LOCATION -> NAS share mounted in the VM
  • Postgres data -> local VM disk
  • Optional later: extra read-only external libraries from other NAS folders

V1 implementation plan

1. Create a dedicated Proxmox VM

Use a Debian 12 or Ubuntu 24.04 LTS VM.

Suggested starting size:

  • 4 vCPU
  • 8 GB RAM
  • 40-80 GB local SSD/NVMe disk for OS + Docker + Postgres + cache

Immich's current requirements say:

  • Linux or Unix-like 64-bit OS recommended
  • minimum 6 GB RAM, recommended 8 GB
  • minimum 2 cores, recommended 4
  • in a virtualized environment, a full VM is recommended
  • storage should support Unix ownership/permissions
  • the Postgres database should ideally use local SSD storage and never a network share
    Source: Immich Requirements.

2. Create a dedicated Synology shared folder for Immich

Create something like:

  • Shared folder: immich-prod

Inside it, keep it simple. Let Immich create its own structure under UPLOAD_LOCATION.

Do not manually invent a lot of subdirectories unless you have a reason.

3. Export that Synology folder to the VM

Prefer NFS from Synology to the Linux VM.

Reason:

  • cleaner Linux permissions model than SMB for this use case
  • easier predictable mount behavior inside a Linux VM

Mount it in the VM, for example:

  • NAS export -> VM mountpoint: /srv/immich-upload

Then point Immich UPLOAD_LOCATION there.

4. Keep local storage for DB and configs

Example local paths in the VM:

  • /opt/immich -> compose files
  • /var/lib/immich-postgres -> database data
  • /var/lib/immich-model-cache -> model cache

The important part is that the Postgres path stays local, not on the NAS.
Source: Immich Requirements.

5. Install Docker Engine + Compose plugin in the VM

Immich requires Docker with the Compose plugin and explicitly requires the command docker compose; docker-compose is deprecated and no longer supported by Immich.
Source: Immich Requirements.

6. Deploy Immich with Docker Compose

Use the official compose example from Immich and modify only what matters:

  • UPLOAD_LOCATION=/srv/immich-upload
  • DB_DATA_LOCATION=/var/lib/immich-postgres
  • model cache on local disk
  • bind only to the VM internally; Pangolin handles public entry

7. Configure Pangolin

Publish Immich via Pangolin on its own subdomain.

Important reverse-proxy requirements from Immich:

  • forward Host
  • forward X-Real-IP
  • forward X-Forwarded-Proto
  • forward X-Forwarded-For
  • allow large uploads
  • Immich must be on the root path of a domain/subdomain
    Source: Immich Reverse Proxy docs.

8. Configure Authentik OIDC for Immich

Immich supports OIDC and explicitly lists Authentik among supported identity providers.
Source: Immich OAuth Authentication.

Create an application/provider pair in Authentik using OAuth2/OIDC. Authentik recommends creating the application and provider together via Applications -> Applications -> Create with provider.
Source: Authentik Create an OAuth2 provider.

Use these redirect URIs in Authentik:

  • app.immich:///oauth-callback
  • https://immich.example.com/auth/login
  • https://immich.example.com/user-settings

Immich requires the mobile redirect URI app.immich:///oauth-callback for iOS/Android app login to work properly.
Source: Immich OAuth Authentication.

Then in Immich Admin -> Settings -> OAuth:

  • enable OAuth
  • set issuer URL to the Authentik OIDC discovery URL
  • set client ID / secret
  • scope: openid email profile
  • auto-register: on
  • auto-launch: optional, keep off in V1

9. Keep password login enabled initially

Do not lock yourself out.

First:

  • create the initial local Immich admin
  • verify normal web login
  • configure OIDC
  • verify browser login
  • verify mobile login
  • only then decide whether to disable password login

Immich allows disabling password authentication instance-wide, but that can lock everyone out if OAuth is also broken.
Source: Immich System Settings.

10. Enable Synology snapshots

Because your Synology is Btrfs, this is a good fit.

Enable snapshots on the immich-prod shared folder.

Good V1 retention example:

  • every hour for 24 hours
  • every day for 14 days
  • every week for 8 weeks

That gives you fast rollback for accidental deletion or a bad import.

Important caveat: snapshots help with rollback, but the full backup still also needs the Immich database and a true backup destination later.


Concrete directory layout

In the VM

/opt/immich/                 # compose + .env
/var/lib/immich-postgres/    # local postgres data
/var/lib/immich-model-cache/ # local ML cache
/srv/immich-upload/          # NFS mount from Synology

On Synology

Shared folder: immich-prod
  \- mounted into VM as /srv/immich-upload

Immich will create and use directories under UPLOAD_LOCATION, including backups for automatic DB dumps. Immich stores automatic database backups in UPLOAD_LOCATION/backups, and those backups only contain metadata, not the photos/videos.
Source: Immich Backup and Restore.


Example Compose shape

This is not a full copy of the official file. It is the shape that matters.

services:
  immich-server:
    image: ghcr.io/immich-app/immich-server:release
    env_file:
      - .env
    volumes:
      - ${UPLOAD_LOCATION}:/data
    ports:
      - "2283:2283"
    depends_on:
      - redis
      - database

  immich-machine-learning:
    image: ghcr.io/immich-app/immich-machine-learning:release
    env_file:
      - .env
    volumes:
      - /var/lib/immich-model-cache:/cache

  redis:
    image: redis:6.2-alpine

  database:
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.0-pgvectors0.8.1
    env_file:
      - .env
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data

And the key bits in .env:

UPLOAD_LOCATION=/srv/immich-upload
DB_DATA_LOCATION=/var/lib/immich-postgres

Use the exact current compose file and image tags from the Immich docs/release example when you deploy, not a random blog post. Immich has changed its Postgres/vector extension story over time and currently documents VectorChord-based setups and upgrade cautions.
Sources: Immich Requirements, Upgrading, Pre-existing Postgres.


Pangolin-specific guidance

Pangolin is an identity-aware remote access platform combining reverse proxy and VPN-style connectivity. For this use case, the key point is: use Pangolin only as the public entrypoint, and keep Immich itself private behind it.
Source: Pangolin GitHub README.

For Immich specifically, make sure Pangolin is configured so that:

  • the service is published on a dedicated host/subdomain
  • uploads are allowed to be large enough
  • timeouts are not too short for big videos
  • forwarded headers match what Immich expects

Because Immich documents strict reverse-proxy expectations, do not rely on defaults you have not checked.
Source: Immich Reverse Proxy docs.


Authentik-specific guidance

In Authentik:

  1. Create an application/provider pair with OAuth2/OIDC.
  2. Use Authorization Code flow.
  3. Use a confidential web client.
  4. Add all redirect URIs you will actually use.

Immich's OAuth docs say the redirect URIs should include:

  • mobile callback
  • web login callback
  • user settings callback

and they should contain all domains used to access Immich.
Source: Immich OAuth Authentication.


What to back up for Immich in this design

You need both:

  1. UPLOAD_LOCATION on the NAS
  2. the database

Immich says a comprehensive backup includes both uploaded photos/videos and the Immich database. It also says the automatic database backups are stored in UPLOAD_LOCATION/backups, but these backups contain only metadata, not photos/videos.
Source: Immich Backup and Restore.

In your design that means:

  • NAS snapshots protect the media path and DB backup files stored under UPLOAD_LOCATION/backups
  • local-VM backup later must also protect /var/lib/immich-postgres or you rely on Immich DB dumps inside UPLOAD_LOCATION/backups

For V1, I would still enable Immich automatic DB backups in the UI.


Minimum test plan for today

  1. VM boots and NFS mount is present at /srv/immich-upload
  2. docker compose up -d starts all Immich services
  3. local browser login works on http://VM-IP:2283
  4. upload one test image and one test video
  5. verify files appear on Synology share
  6. configure Pangolin and verify public HTTPS access
  7. configure Authentik OIDC and verify browser login
  8. verify mobile app login using OIDC
  9. create a manual DB backup in Immich and confirm it appears under UPLOAD_LOCATION/backups
  10. create a Synology snapshot and verify the snapshot schedule is active

Final recommendation

For your V1 today, the clean setup is:

  • Proxmox VM for Immich
  • Docker Compose inside the VM
  • local VM disk for Postgres and local runtime state
  • Synology NFS share for UPLOAD_LOCATION
  • Synology Btrfs snapshots on that shared folder
  • Pangolin for public HTTPS exposure
  • Authentik OIDC for login

That is the right compromise between best practice and what you want to achieve right now.

The one thing not to compromise on

Do not place the Immich Postgres data on the NAS share. That is the main thing Immich explicitly warns against.
Source: Immich Requirements.