Deploy native Jellyfin service on Lyra #190
No reviewers
Labels
No labels
area:authentication
area:flake-utilities
area:performance
area:tbd
host:chaos
host:electra
host:fleet
host:lyra
host:nova
host:vega
investigation
phase:cutover
phase:deploy
phase:mcp
phase:module
phase:packaging
phase:prep
phase:validation
priority:high
priority:medium
project:attic-postgres-lyra-rollout
project:auto-update-reliability
project:auto-update-remediation
project:declarative-purity-cleanup
project:external-review
project:fleet-boundary-cleanup
project:host-facts-refactor
project:lyra-nixos-deploy
project:lyra-service-stack-migration
project:nebula-mesh-network
project:nixos-build-deployment-pipeline
project:security-hardening
project:service-stack-migration
project:vega-sillytavern-cutover
project:wiki-rebuild
repo:numtide/flake-utils
repo:numtide/nix-auth
repo:numtide/nixos-passthru-cache
repo:numtide/nix-relay
service:auto-update
service:mem0
service:nix
service:sillytavern
service:slskd
service:synthseek
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
nimmo/nixos-config!190
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/issue-30-native-jellyfin-prep"
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?
Summary
/var/lib/jellyfinand/var/cache/jellyfinlocationsmedia-libraryNFS module for/mnt/mediaand future host migrationsValidation
nix flake checkpassesjellyfinRequires = [ "mnt-media.mount" ]192.168.8.238:/volume1/mediaat/mnt/media, read-only over NFS 4.1just testcompleted on LyraLive deployment evidence
This native replacement has already been deployed and tested on Lyra, replacing the stopped Docker container. Library access and real video playback are confirmed working. During the playback test Jellyfin selected CUDA hardware decoding,
scale_cuda, and RTX 4070hevc_nvencencoding, then continued reporting an active playback session without CUDA, NVENC, media-access, or FFmpeg errors.The stopped pre-cutover snapshot remains available for the rollback window; this MR does not delete the imported state or source snapshot.
Closes #30
Automated code review
Reviewed commit:
c9c905fd23b2add7c5d5a99ca8e1bc1c09939accVerdict: Requires further work
Resolve the blocking or important findings and investigate failed deterministic checks before merging.
Overall assessment
The PR introduces a native Jellyfin service and a reusable NFS media-library module on the Lyra host, replacing a Docker-based setup. It configures NVIDIA hardware acceleration, hard dependencies on the NFS mount to prevent scanning empty directories, and integrates with existing backup and failure monitoring systems. The reviewer notes that the NFS mount timeout is intentional and bounded, and that
nofailwas removed to align with Jellyfin's hard dependency.Blocking findings
None.
Important findings
"x-systemd.mount-timeout=30s"
Impact: If the NFS server is unreachable during boot, the system will wait up to 30 seconds for each mount attempt before failing or timing out, potentially delaying boot or service startup.
Suggested fix: Consider if 30s is sufficient for your network conditions. If the NAS is often unavailable,
nofailmight be appropriate for non-critical mounts, but Jellyfin's hard dependency (Requires=) means the mount must succeed for Jellyfin to start. The current setup is consistent with the stated goal of preventing Jellyfin from scanning an empty mount.Suggestions
Jellyfin service failure monitoring coverage (modules/services/jellyfin.nix:92; high confidence)
services.serviceFailureMonitor.services = lib.mkAfter [ "jellyfin" ];
Impact: Ensures Jellyfin is monitored for failures. This is good practice.
Suggested fix: No action needed; this is a positive finding confirming proper integration with the existing failure monitoring system.
Backup data path configuration (modules/services/jellyfin.nix:91; high confidence)
nixosConfig.backup.dataPaths = lib.mkAfter [ dataDir ];
Impact: Ensures Jellyfin's state directory is included in backups. This is critical for preserving library metadata and settings.
Suggested fix: No action needed; this is a positive finding confirming proper backup integration.
NVIDIA device access configuration (modules/services/jellyfin.nix:70; high confidence)
DeviceAllow = [ "char-nvidiactl rw" "char-nvidia-caps rw" "char-nvidia-frontend rw" "char-nvidia-uvm rw" ];
Impact: Explicitly grants Jellyfin access to necessary NVIDIA devices for hardware acceleration. This is more secure than
PrivateDevices = falsealone.Suggested fix: No action needed; this is a positive finding confirming proper security hardening for GPU access.
Tests and validation
Questions
media-librarymodule been tested on any host other than Lyra to ensure its reusability?/mnt/mediathat might need similar NFS mount configuration?Review limitations
Diff coverage
README.md: reviewed — included in a context-limited batchhosts/lyra/default.nix: reviewed — included in a context-limited batchmodules/services/jellyfin.nix: reviewed — included in a context-limited batchmodules/services/media-library.nix: reviewed — included in a context-limited batchReview metadata
Addressed the automated review in
ea35684.findmntpreflight. Jellyfin still hasRequires=andAfter=onmnt-media.mount, plusRequiresMountsFor=/mnt/media, so the generated mount unit remains the authoritative hard dependency. The only evaluatedExecStartPrenow is the upstream NixOS Jellyfin pre-start script.nixosConfig.mediaLibrary.sourcerequired instead of embedding the Lyra NAS IP as a reusable-module default. Lyra now sets192.168.8.238:/volume1/mediaexplicitly.The 30-second mount timeout is intentional as a bounded startup wait; the deployed mount established successfully, while
hard,timeo=600,retrans=2governs established NFS I/O. The former LSIO identity/environment handling is not required by the native service: native state ownership is managed by the NixOS module, UI-managed configuration was imported, and NVIDIA access and transcoding are declared injellyfin.nix.Validation after the changes: full
nix flake checkpasses; evaluated Lyra configuration preservesRequires=["mnt-media.mount"]and the same NAS export.Addressed the updated automated review blocker in
c9c905f.nofailfrom the shared media mount so its failure policy now matches Jellyfin's hard dependency./mnt/mediamountpoint when the NAS export is unavailable.The Docker state migration was performed before the final MR configuration was committed. The imported native state is already running from
/var/lib/jellyfinand/var/cache/jellyfin; the one-time importer was intentionally removed only after live startup, library, playback, and RTX 4070 transcoding validation succeeded.Validation: full
nix flake checkpasses. Evaluated Lyra configuration has nonofailoption, preserves the explicit NAS export, and keepsRequires=["mnt-media.mount"]for Jellyfin.Reviewed the
c9c905fautomated result. No further code change is warranted for the remaining timeout observation.The 30-second value is a maximum bounded wait, not an observed startup delay. Lyra and the NAS are on the same LAN, and repeated live activations mounted the export successfully without approaching the timeout. If the NAS is unavailable, delaying the required media mount and leaving Jellyfin stopped is preferable to starting Jellyfin against an empty directory. The latest review also confirms that this is internally consistent with the stated safety policy.
The reusable module has not yet been deployed on another host; Lyra is its canary. No other native Lyra service currently consumes
/mnt/media. Existing Docker stacks retain their own mounts, while future native migrations can opt into this module explicitly.