Files
chiasson-nix/modules/hosts/14900k/_private/jellyfin-nfs-export.nix
T
2026-05-15 00:24:13 -03:00

81 lines
3.3 KiB
Nix

# NFS exports from nixdesk (14900k) to nix-server (192.168.2.238):
# - /mnt/test/jellyfin → nix-server /mnt/nixdesk-jellyfin (Jellyfin bulk libraries)
# - /mnt/media → nix-server /mnt/media (Btrfs MediaLibrary disk; see media-disk.nix)
#
# NTFS on nixdesk uses uid=olivier + gid=nfsmedia (990); dirs here are olivier:nfsmedia 2775 so
# local writes and NFS all_squash (anonuid=olivier, anongid=990) get rwx via owner or group.
#
# Legacy trees may still need a one-time `chgrp -R nfsmedia` / `chmod -R g+rwX` on deep folders.
{ config, pkgs, ... }:
let
olivierUid = config.users.users.olivier.uid or 1000;
in
{
# Avoid UID/GID mismatches across machines: map all NFS writes from nix-server to a single
# local system user/group on this server.
users.groups.nfsmedia = { gid = 990; };
users.users.nfsmedia = {
isSystemUser = true;
uid = 990;
group = "nfsmedia";
};
# olivier: owner for local use; nfsmedia: group matches NTFS gid=990 and NFS all_squash (990).
systemd.tmpfiles.settings."14900k-nfs-export-paths" = {
"/mnt/test"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/test/jellyfin"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/test/jellyfin/movies"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/test/jellyfin/tv"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media/Movies"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media/TV"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media/Videos"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
};
# After exports are up, ensure group nfsmedia can write throughout library roots (idempotent;
# scoped to library folders only — not whole disks). Runs on each `nixos-rebuild switch`.
system.activationScripts.nfs-export-group-write = {
deps = [ "specialfs" ];
text = ''
for d in \
/mnt/media/TV /mnt/media/Movies /mnt/media/Videos \
/mnt/test/jellyfin/tv /mnt/test/jellyfin/movies
do
[ -d "$d" ] || continue
${pkgs.acl}/bin/setfacl -R -m g:nfsmedia:rwx "$d" 2>/dev/null || true
${pkgs.acl}/bin/setfacl -R -d -m g:nfsmedia:rwx "$d" 2>/dev/null || true
done
'';
};
# Fixed ports so the firewall can allow NFS v3 helpers (see networking.firewall below).
services.nfs.server = {
enable = true;
mountdPort = 4000;
lockdPort = 4001;
statdPort = 4002;
# fsid= unique per export tree (avoids client ESTALE when multiple paths are exported).
# Squash nix-server clients to olivier:nfsmedia so Jellyfin can write .nfo/posters into
# existing olivier-owned library folders (990-only squash was "other" r-x on typical 755 trees).
exports = ''
/mnt/test/jellyfin 192.168.2.238(rw,sync,no_subtree_check,crossmnt,root_squash,all_squash,anonuid=${toString olivierUid},anongid=990,fsid=1)
/mnt/media 192.168.2.238(rw,sync,no_subtree_check,crossmnt,root_squash,all_squash,anonuid=${toString olivierUid},anongid=990,fsid=2)
'';
};
networking.firewall.allowedTCPPorts = [
111 # portmapper
2049
4000
4001
4002
];
networking.firewall.allowedUDPPorts = [
111
2049
4000
4001
4002
];
}