{ lib, ... }: { services.jellyfin = { enable = true; dataDir = "/mnt/data/AppData/jellyfin"; cacheDir = "/mnt/data/AppData/jellyfin/cache"; }; # "users" so the shared library stays readable (see the UMask note below); # "video"/"render" for the DRI nodes used by hardware transcoding. renderD128 # happens to be 0666 so VAAPI alone would work without this, but card1 is # 0660 root:video — and neither mode is guaranteed, so don't rely on it. The # groups are harmless on a host with no GPU: they exist regardless, and this # module stays host-agnostic (the DRIVER is enabled per-host, e.g. jupiter's # hardware.graphics + intel-media-driver). users.users.jellyfin.extraGroups = [ "users" "video" "render" ]; # The upstream module hardcodes UMask=0077 — root cause of jellyfin writing # trickplay thumbnails into stray new show folders it invented itself, # owned jellyfin:jellyfin 700, invisible to every other service sharing # the library (cinephage, mediamanager, ...). New files/dirs it creates # from here on inherit group "users" (library roots are setgid, see the # one-time chmod g+s done by hand) and stay group-writable. systemd.services.jellyfin.serviceConfig.UMask = lib.mkForce "0002"; }