feat(web-arm): deploy Immich with Authelia OIDC, group-gated access #178
Labels
No labels
bug
enhancement
in-progress
needs-info
needs-triage
p0
ready-for-agent
ready-for-human
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/nixos#178
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Deploy Immich on web-arm using the native
services.immichmodule (nixpkgs 26.05), fronted athttps://immich.cloonar.com, with login via Authelia OIDC restricted to members of theimmichLDAP group. Photo originals live on a slow Hetzner Storage-Box CIFS share; thumbnails stay on local SSD. Machine learning is on but CPU-throttled so it never starves the websites.This is the thinnest end-to-end slice: a working, access-gated, empty Immich you can log into. Data migration is a separate human issue.
Human prerequisites (already done — do NOT redo)
immich-oidc-client-secret(plaintext OIDC client secret) present inhosts/web-arm/secrets.yaml.immich-smb-credentials(CIFSusername=…/password=…) present inhosts/web-arm/secrets.yaml.groupOfNamescn=immich,ou=groups,dc=cloonar,dc=comexists with the admin asmember.immich.cloonar.com→ web-arm.//u149513.your-backup.de/u149513-sub12/.secret:$pbkdf2-sha512$310000$GeKgtfu/HhHSY9UmOOSeaQ$zgMVpKEkQlG1Bt6Tvf2Bq.lrTdIxgLbix8MuVwVwMTo3hw2qjeAoFuEb8DyTCYQh3G.orhqoNOyETBCD9iyWeAImplementation
Create
hosts/web-arm/modules/immich/default.nix, import it fromhosts/web-arm/configuration.nix. Host-local module style: inline concrete values, nooptions/mkIfboilerplate.1. Immich service (native module)
enable = true;host = "127.0.0.1",port = 2283,openFirewall = false(nginx fronts it).mediaLocation = "/var/lib/immich"(local SSD).database.enable = true/database.createDB = true— reuses the existingpostgresql_14instance; the module adds the immich DB + pgvector/vectorchord and flipsshared_preload_libraries. ⚠️ First deploy restarts Postgres, briefly interrupting PowerSync/Grafana — expected; call it out in the commit message.redis.enable = true(the module's own immich redis instance — do NOT share authelia's).machine-learning.enable = true.users.users.immich.uid+users.groups.immich.gidto a free id so the CIFS mount can map ownership (mirror how nextcloud's uid/gid are fixed).2. Storage split — originals on CIFS, thumbnails local
Only
library/(originals) goes to CIFS;thumbs/,upload/,profile/stay on local SSD under/var/lib/immich.sops.secrets.immich-smb-credentials = {};(root-readable is fine — the mount reads it at mount time).RequiresMountsFor = "/var/lib/immich/library"onimmich-server), and ensure/var/lib/immichexists owned by immich before the mount (the module'sStateDirectoryhandles the parent). Verify the CIFS submount is writable by the immich user after deploy.3. Declarative system config via sops template (OAuth + password-login off + transcoding off + ML + job concurrency)
Render the Immich config JSON with the OIDC secret injected from sops; point Immich at it. This keeps the secret out of the world-readable Nix store.
⚠️ The Immich config schema drifts between releases. The keys above are the intended settings, not guaranteed verbatim — validate exact key names / enum values against the Immich version shipped in 26.05 before relying on them (esp.
ffmpeg.transcode's enum and thejob.*.concurrencykeys). A bad key fails startup — checkjournalctl -u immich-serverafter deploy. Once a config file is present, the entire system-settings UI is read-only by design.4. CPU throttling — websites stay snappy, ML/thumbs just take longer
Default
CPUWeightis 100, which the websites keep — so under contention they get ~5× the share; when the box is idle Immich runs full speed.5. Authelia OIDC client + authorization policy (
hosts/web-arm/modules/authelia.nix)Add the policy:
Add the client to
identity_providers.oidc.clients:No
claims_policyneeded — access is gated at Authelia, so Immich doesn't need the groups claim. If the mobile app's custom-scheme redirect is rejected, switch to ImmichmobileOverrideEnabled+ registerhttps://immich.cloonar.com/api/oauth/mobile-redirect.6. nginx vhost
7. Backups
/var/lib/immichto the borgexcludelist inutils/modules/borgbackup.nix(CIFS originals must not be pulled over the wire; thumbs are regenerable) — mirror the existingdont backup nextcloudline with a comment.services.postgresqlBackupalready dumps all DBs (immich auto-included); borg picks up/var/backup/postgresql.Acceptance criteria
https://immich.cloonar.comserves Immich over TLS.group:immichmember can log in (first login becomes the Immich admin); a non-member is denied at Authelia./var/lib/immich/library(CIFS) and its thumbnail appears under local/var/lib/immich/thumbs.immich-server+immich-machine-learningrun withCPUWeight=20;journalctlshows no config-schema errors.Notes / risks
system.stateVersion.