feat: add jellyfin and hardware acceleration for transcoding

This commit is contained in:
2025-11-25 19:48:52 +01:00
parent d7d3722ce7
commit 59a37c9b46
5 changed files with 104 additions and 0 deletions

View File

@@ -135,6 +135,7 @@
# multimedia
"/dl.cloonar.com/${config.networkPrefix}.97.5"
"/jellyfin.cloonar.com/${config.networkPrefix}.97.5"
"/deconz.cloonar.multimedia/${config.networkPrefix}.97.22"

View File

@@ -20,6 +20,7 @@ let
group = "jellyfin";
home = "/var/lib/jellyfin";
createHome = true;
extraGroups = [ "render" "video" ];
};
jellyfinGroup = {
gid = cids.gids.jellyfin;
@@ -49,7 +50,31 @@ in
hostAddress = "${networkPrefix}.97.1";
localAddress = "${networkPrefix}.97.11/24";
# GPU device passthrough for hardware transcoding
allowedDevices = [
{
modifier = "rwm";
node = "/dev/dri/card0";
}
{
modifier = "rwm";
node = "/dev/dri/renderD128";
}
];
bindMounts = {
"/dev/dri" = {
hostPath = "/dev/dri";
isReadOnly = false;
};
"/run/opengl-driver" = {
hostPath = "/run/opengl-driver";
isReadOnly = true;
};
"/nix/store" = {
hostPath = "/nix/store";
isReadOnly = true;
};
"/var/lib/pyload" = {
hostPath = "/var/lib/pyload";
isReadOnly = false;
@@ -78,6 +103,21 @@ in
unrar # Required for RAR archive extraction
];
# Intel graphics support for hardware transcoding
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
vpl-gpu-rt
intel-compute-runtime
];
};
# Set VA-API driver to iHD (modern Intel driver for N100)
environment.sessionVariables = {
LIBVA_DRIVER_NAME = "iHD";
};
networking = {
hostName = "pyload";
useHostResolvConf = false;
@@ -101,6 +141,21 @@ in
openFirewall = true;
};
# Override systemd hardening for GPU access
systemd.services.jellyfin = {
serviceConfig = {
PrivateUsers = lib.mkForce false; # Disable user namespacing - breaks GPU device access
DeviceAllow = [
"/dev/dri/card0 rw"
"/dev/dri/renderD128 rw"
];
SupplementaryGroups = [ "render" "video" ]; # Critical: Explicit group membership for GPU access
};
environment = {
LIBVA_DRIVER_NAME = "iHD"; # Ensure service sees this variable
};
};
# Disable SSL certificate verification
systemd.services.pyload = {
environment = {
@@ -121,6 +176,10 @@ in
};
};
# Ensure render/video groups exist with consistent GIDs for GPU access
users.groups.render = { gid = 303; };
users.groups.video = { gid = 26; };
users.users.pyload = pyloadUser;
users.groups.pyload = pyloadGroup;
users.users.jellyfin = jellyfinUser;

View File

@@ -6,6 +6,7 @@
podman = 10004;
foundry-vtt = 10005;
pyload = 10006;
jellyfin = 10007;
};
gids = {
unbound = 10001;
@@ -14,5 +15,6 @@
podman = 10004;
foundry-vtt = 10005;
pyload = 10006;
jellyfin = 10007;
};
}

View File

@@ -50,4 +50,34 @@
proxyWebsockets = true;
};
};
services.nginx.virtualHosts."jellyfin.cloonar.com" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
# Restrict to internal LAN only
extraConfig = ''
allow ${config.networkPrefix}.96.0/24;
allow ${config.networkPrefix}.98.0/24;
allow ${config.networkPrefix}.99.0/24;
deny all;
'';
locations."/" = {
proxyPass = "http://${config.networkPrefix}.97.11:8096";
proxyWebsockets = true;
extraConfig = ''
# Jellyfin-specific headers for proper streaming
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering for better streaming performance
proxy_buffering off;
'';
};
};
}