My nix-darwin and NixOS config
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: decouple Immich from Nextcloud

+10 -48
+8 -42
modules/immich.nix
··· 4 4 # Architecture: 5 5 # Immich server (127.0.0.1:cfg.immich.port) 6 6 # ↑ reverse proxy 7 - # Caddy (http://immich.ewancroft.uk:cfg.immich.caddyPort) 8 - # ↑ Cloudflare Tunnel (outbound only, no firewall ports needed) 7 + # Caddy (https://immich.ewancroft.uk — tailnet only) 9 8 # 10 - # Storage — shared with Nextcloud: 11 - # Media lives at cfg.immich.mediaDir, which defaults to 12 - # /srv/nextcloud/data/ewan/files/Photos — inside the Nextcloud user files 13 - # tree. This means: 14 - # • Photos uploaded via the Immich mobile app appear in Nextcloud. 15 - # • Photos synced to Nextcloud via the desktop client appear in Immich 16 - # (picked up by the nextcloud-files-scan timer, which runs daily). 17 - # 18 - # Permissions: 19 - # The `immich` user is added to the `nextcloud` group. The Photos directory 20 - # is created with mode 2770 (setgid) so all files created inside inherit 21 - # the nextcloud group, keeping Nextcloud happy when it scans them. 22 - # Nextcloud's own data directory is group-traversable (0750) by default, 23 - # so group membership is sufficient for access. 9 + # Storage: 10 + # Media lives at cfg.immich.mediaDir (default: /srv/immich), owned by the 11 + # immich user. Completely independent of Nextcloud. 24 12 # 25 13 # Database & cache: 26 14 # PostgreSQL and Redis are managed locally by NixOS (separate instances ··· 28 16 # 29 17 # First-run: 30 18 # Navigate to https://immich.ewancroft.uk and complete the onboarding 31 - # wizard to create your admin account. Then configure the library path 32 - # to cfg.immich.mediaDir from the UI. 19 + # wizard to create your admin account. 33 20 ############################################################################## 34 21 { 35 22 config, ··· 42 29 in 43 30 lib.mkIf cfg.services.immich.enable { 44 31 45 - # ── User / group ───────────────────────────────────────────────────────── 46 - # Add immich to the nextcloud group so it can read/write inside the 47 - # Nextcloud data tree with the setgid directories created below. 48 - users.users.immich = { 49 - extraGroups = [ "nextcloud" ]; 50 - }; 51 - 52 32 # ── Storage ─────────────────────────────────────────────────────────────── 53 - # Create the Photos directory inside the Nextcloud user files tree. 54 - # Mode 2770: owner=nextcloud, group=nextcloud, setgid so new files 55 - # inherit the group — Nextcloud's scanner expects group-owned files. 56 33 systemd.tmpfiles.rules = [ 57 - # Ensure the Media parent (shared with Jellyfin) exists even if jellyfin.nix 58 - # is disabled. Referencing cfg.jellyfin.mediaDir directly avoids builtins.dirOf, 59 - # which strips option context and causes an activation-script derivation warning. 60 - "d ${cfg.jellyfin.mediaDir} 2770 nextcloud nextcloud -" 61 - "d ${im.mediaDir} 2770 nextcloud nextcloud -" 34 + "d ${im.mediaDir} 0770 immich immich -" 62 35 ]; 63 36 64 37 # ── Immich service ──────────────────────────────────────────────────────── ··· 69 42 host = "127.0.0.1"; 70 43 port = im.port; 71 44 72 - # Point at the shared directory inside the Nextcloud data tree. 73 45 mediaLocation = im.mediaDir; 74 46 75 47 # Local PostgreSQL — NixOS creates a dedicated DB and user automatically. ··· 79 51 redis.enable = true; 80 52 }; 81 53 82 - # Wait for /srv (and Nextcloud's initial setup) before starting Immich, 83 - # so the Photos directory is guaranteed to exist with correct ownership. 54 + # Wait for /srv before starting Immich so the media directory exists. 84 55 systemd.services.immich-server = { 85 - after = [ 86 - "srv.mount" 87 - "nextcloud-setup.service" 88 - ]; 56 + after = [ "srv.mount" ]; 89 57 wants = [ "srv.mount" ]; 90 58 }; 91 59 92 60 # ── Caddy reverse proxy ─────────────────────────────────────────────────── 93 61 # Tailscale direct route — bypasses Cloudflare (no upload size limit). 94 62 # Let's Encrypt wildcard cert (*.ewancroft.uk) via Cloudflare DNS-01. 95 - # Reachable from any tailnet device at https://${im.hostname} once split-dns 96 - # is configured in the Tailscale admin console (see modules/split-dns.nix). 97 63 services.caddy.virtualHosts."http://${im.hostname}" = lib.mkIf (cfg.server.tailscaleIP != "") { 98 64 extraConfig = '' 99 65 bind ${cfg.server.tailscaleIP}
+2 -6
modules/options.nix
··· 486 486 }; 487 487 mediaDir = mkOption { 488 488 type = str; 489 - default = "/srv/nextcloud/data/ewan/files/Media/Photos"; 490 - description = '' 491 - Primary media directory for Immich. Defaults to inside the Nextcloud 492 - user files tree so that photos synced via Nextcloud clients are visible in 493 - Immich, and vice-versa (the nextcloud-files-scan timer picks up writes daily). 494 - Override this if nextcloud.dataDir or nextcloud.adminUser differ from defaults.''; 489 + default = "/srv/immich"; 490 + description = "Primary media directory for Immich uploads and assets."; 495 491 }; 496 492 }; 497 493