feat(immich): migrate Lyra to native NixOS services #218

Merged
nimmo merged 8 commits from feat/issue-31-native-immich into main 2026-09-11 17:55:38 +01:00
Owner

Summary

  • Replace the Lyra Docker Immich application stack with native NixOS Immich, Redis, and machine-learning services.
  • Provision the Immich PostgreSQL role, database, VectorChord/pgvector support, and SOPS-backed password on Vega.
  • Mount the existing library at /mnt/immich, migrate the restored database paths, and preserve the Docker stack as the rollback source.
  • Configure CUDA-enabled ONNX Runtime for Immich ML, targeting Lyra's RTX 4070; the first large CUDA build will be completed on Nova after merge.

Validation

  • nix flake check passes.
  • Vega has been deployed to this branch.
  • Lyra native Immich started successfully, completed mount and database checks, and returned {"res":"pong"} from /api/server/ping.
  • The Immich API and microservices both report the ML service healthy.

Follow-up

  • Build the CUDA ML closure on Nova, then verify CUDAExecutionProvider and a real ML job on Lyra.

Refs #31

## Summary - Replace the Lyra Docker Immich application stack with native NixOS Immich, Redis, and machine-learning services. - Provision the Immich PostgreSQL role, database, VectorChord/pgvector support, and SOPS-backed password on Vega. - Mount the existing library at `/mnt/immich`, migrate the restored database paths, and preserve the Docker stack as the rollback source. - Configure CUDA-enabled ONNX Runtime for Immich ML, targeting Lyra's RTX 4070; the first large CUDA build will be completed on Nova after merge. ## Validation - `nix flake check` passes. - Vega has been deployed to this branch. - Lyra native Immich started successfully, completed mount and database checks, and returned `{"res":"pong"}` from `/api/server/ping`. - The Immich API and microservices both report the ML service healthy. ## Follow-up - Build the CUDA ML closure on Nova, then verify `CUDAExecutionProvider` and a real ML job on Lyra. Refs #31
docs(immich): retire completed migration runbook
All checks were successful
AI pull-request review / review (pull_request) Successful in 1m27s
Build and Push Attic Cache / test (pull_request) Successful in 1m30s
Build and Push Attic Cache / build (pull_request) Has been skipped
Build and Push Attic Cache / pin-lifecycle (pull_request) Has been skipped
Build and Push Attic Cache / remediate (pull_request) Has been skipped
Build and Push Attic Cache / notify-remediation (pull_request) Has been skipped
Build and Push Attic Cache / record-remediation-notify-failure (pull_request) Has been skipped
be587b29f0
Author
Owner

Automated code review

Reviewed commit: 21cd109e553d04bea17764da03c58a53fe1f5baf

Verdict: Requires further work

Resolve the blocking or important findings and investigate failed deterministic checks before merging.

Overall assessment

The PR migrates Immich from Docker to native NixOS services, splitting the stack across two hosts: Vega (PostgreSQL) and Lyra (Application/ML). It introduces new modules for database setup and service configuration, configures SOPS secrets with specific age keys, and enables CUDA acceleration on Lyra's RTX 4070. The diff shows careful systemd ordering for PostgreSQL extensions and password setting, as well as NFS mount dependencies.

Blocking findings

None.

Important findings

  • Missing Nebula dependency in Immich systemd units (modules/services/immich.nix:145; high confidence)
    The systemd.services block for immich-server and immich-machine-learning sets requires = [ "network-online.target" "sops-nix.service" ]; and after = [ ... ]. It does not include nebula@mesh.service. However, the NFS mount (line 108) correctly requires Nebula, and the Immich service depends on the NFS mount via RequiresMountsFor. Since the database host is a Nebula address (10.10.0.2), if the network stack initializes but Nebula routing is not yet established when Immich starts (even with retries), it may fail to connect.
    Impact: Potential transient connection failures during boot if Nebula connectivity is slower than the Immich service startup/retry logic.
    Suggested fix: Add wants = [ "nebula@mesh.service" ]; and after = [ "nebula@mesh.service" ]; to the Immich systemd units to ensure network routing is ready before attempting database connections.

Suggestions

  • Hardcoded CUDA compute capability (hosts/lyra/default.nix:98; medium confidence)
    nixpkgs.config.cudaCapabilities = [ "8.9" ]; is hardcoded.
    Impact: This is correct for the RTX 4070 (Ada Lovelace). It reduces build times and binary size. If hardware changes, this must be updated manually.
    Suggested fix: Consider documenting this assumption or making it an option if future hardware upgrades are anticipated.

  • SOPS key rotation complexity (.sops.yaml:387; medium confidence)
    The secrets/immich.yaml file includes multiple age keys (vega, lyra, yubikey-nano5c, yubikey-5-nfc, provision-key).
    Impact: Rotating these keys requires re-encrypting the secret with the new key set and distributing it to all authorized parties.
    Suggested fix: Ensure the team is aware of the key rotation procedure for this specific secret file.

Tests and validation

  • No configured deterministic checks.

Questions

  • Has the immich NixOS module been verified to handle database connection retries gracefully if PostgreSQL is not immediately available at boot?
  • Is there a plan to monitor the performance of the CUDA-enabled ONNX Runtime on Lyra's RTX 4070 to ensure it meets expectations for face recognition and smart search?

Review limitations

  • I cannot run nix flake check or deploy the configuration to verify runtime behavior.
  • I cannot validate the SOPS encryption/decryption process or the actual secret values.
  • I cannot test the CUDA build on Nova or the ML job execution on Lyra as described in the follow-up.

Diff coverage

  • .sops.yaml: reviewed — included in a context-limited batch
  • hosts/lyra/default.nix: reviewed — included in a context-limited batch
  • hosts/vega/default.nix: reviewed — included in a context-limited batch
  • modules/databases/immich.nix: reviewed — included in a context-limited batch
  • modules/services/immich.nix: reviewed — included in a context-limited batch
  • secrets/immich.yaml: reviewed — included in a context-limited batch
Review metadata
  • Reviewer: forgejo-ai-review v1
  • Model: qwen3.6:35b-a3b-q8_0
  • Guidance loaded: .forgejo/ai-review.md, .forgejo/ai-review.yml, AGENTS.md, README.md
  • Commits considered: 8
  • Previous automated review: updated
  • Findings: 3
<!-- forgejo-ai-review:v1 --> ## Automated code review Reviewed commit: `21cd109e553d04bea17764da03c58a53fe1f5baf` ## Verdict: Requires further work Resolve the blocking or important findings and investigate failed deterministic checks before merging. ### Overall assessment The PR migrates Immich from Docker to native NixOS services, splitting the stack across two hosts: Vega (PostgreSQL) and Lyra (Application/ML). It introduces new modules for database setup and service configuration, configures SOPS secrets with specific age keys, and enables CUDA acceleration on Lyra's RTX 4070. The diff shows careful systemd ordering for PostgreSQL extensions and password setting, as well as NFS mount dependencies. ### Blocking findings None. ### Important findings - **Missing Nebula dependency in Immich systemd units** (modules/services/immich.nix:145; high confidence) The `systemd.services` block for `immich-server` and `immich-machine-learning` sets `requires = [ "network-online.target" "sops-nix.service" ];` and `after = [ ... ]`. It does not include `nebula@mesh.service`. However, the NFS mount (line 108) correctly requires Nebula, and the Immich service depends on the NFS mount via `RequiresMountsFor`. Since the database host is a Nebula address (`10.10.0.2`), if the network stack initializes but Nebula routing is not yet established when Immich starts (even with retries), it may fail to connect. Impact: Potential transient connection failures during boot if Nebula connectivity is slower than the Immich service startup/retry logic. Suggested fix: Add `wants = [ "nebula@mesh.service" ];` and `after = [ "nebula@mesh.service" ];` to the Immich systemd units to ensure network routing is ready before attempting database connections. ### Suggestions - **Hardcoded CUDA compute capability** (hosts/lyra/default.nix:98; medium confidence) `nixpkgs.config.cudaCapabilities = [ "8.9" ];` is hardcoded. Impact: This is correct for the RTX 4070 (Ada Lovelace). It reduces build times and binary size. If hardware changes, this must be updated manually. Suggested fix: Consider documenting this assumption or making it an option if future hardware upgrades are anticipated. - **SOPS key rotation complexity** (.sops.yaml:387; medium confidence) The `secrets/immich.yaml` file includes multiple age keys (vega, lyra, yubikey-nano5c, yubikey-5-nfc, provision-key). Impact: Rotating these keys requires re-encrypting the secret with the new key set and distributing it to all authorized parties. Suggested fix: Ensure the team is aware of the key rotation procedure for this specific secret file. ### Tests and validation - No configured deterministic checks. ### Questions - Has the `immich` NixOS module been verified to handle database connection retries gracefully if PostgreSQL is not immediately available at boot? - Is there a plan to monitor the performance of the CUDA-enabled ONNX Runtime on Lyra's RTX 4070 to ensure it meets expectations for face recognition and smart search? ### Review limitations - I cannot run `nix flake check` or deploy the configuration to verify runtime behavior. - I cannot validate the SOPS encryption/decryption process or the actual secret values. - I cannot test the CUDA build on Nova or the ML job execution on Lyra as described in the follow-up. ### Diff coverage - `.sops.yaml`: **reviewed** — included in a context-limited batch - `hosts/lyra/default.nix`: **reviewed** — included in a context-limited batch - `hosts/vega/default.nix`: **reviewed** — included in a context-limited batch - `modules/databases/immich.nix`: **reviewed** — included in a context-limited batch - `modules/services/immich.nix`: **reviewed** — included in a context-limited batch - `secrets/immich.yaml`: **reviewed** — included in a context-limited batch <details><summary>Review metadata</summary> - Reviewer: forgejo-ai-review v1 - Model: qwen3.6:35b-a3b-q8_0 - Guidance loaded: .forgejo/ai-review.md, .forgejo/ai-review.yml, AGENTS.md, README.md - Commits considered: 8 - Previous automated review: updated - Findings: 3 </details>
fix(immich): order startup dependencies
All checks were successful
AI pull-request review / review (pull_request) Successful in 1m15s
Build and Push Attic Cache / test (pull_request) Successful in 1m28s
Build and Push Attic Cache / build (pull_request) Has been skipped
Build and Push Attic Cache / pin-lifecycle (pull_request) Has been skipped
Build and Push Attic Cache / remediate (pull_request) Has been skipped
Build and Push Attic Cache / notify-remediation (pull_request) Has been skipped
Build and Push Attic Cache / record-remediation-notify-failure (pull_request) Has been skipped
21cd109e55
nimmo merged commit 141a660df3 into main 2026-09-11 17:55:38 +01:00
nimmo deleted branch feat/issue-31-native-immich 2026-09-11 17:55:38 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nimmo/nixos-config!218
No description provided.