2024-07-12 18:11:26 +00:00
|
|
|
{
|
|
|
|
pkgs,
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
cfg = config.aux.system.services.jellyfin;
|
2024-07-15 14:36:44 +00:00
|
|
|
|
2024-11-19 15:39:47 +00:00
|
|
|
jellyfin-audio-save = pkgs.unstable.jellyfin.overrideAttrs (
|
2024-12-06 16:16:58 +00:00
|
|
|
finalAttrs: prevAttrs: { patches = [ ./jellyfin-audio-save-position.patch ]; }
|
2024-07-15 14:36:44 +00:00
|
|
|
);
|
2024-07-12 18:11:26 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
aux.system.services.jellyfin = {
|
2024-09-08 15:58:56 +00:00
|
|
|
enable = lib.mkEnableOption "Enables the Jellyfin media streaming service.";
|
2024-07-12 18:11:26 +00:00
|
|
|
home = lib.mkOption {
|
2024-09-07 17:44:14 +00:00
|
|
|
default = "/var/lib/jellyfin";
|
2024-07-12 18:11:26 +00:00
|
|
|
type = lib.types.str;
|
|
|
|
description = "Where to store Jellyfin's files";
|
|
|
|
};
|
|
|
|
url = lib.mkOption {
|
|
|
|
default = "";
|
|
|
|
type = lib.types.str;
|
|
|
|
description = "The complete URL where Jellyfin is hosted.";
|
|
|
|
example = "https://jellyfin.example.com";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
|
|
aux.system.users.media.enable = true;
|
|
|
|
|
|
|
|
services = {
|
|
|
|
nginx.virtualHosts."${cfg.url}" = {
|
2024-12-06 16:16:58 +00:00
|
|
|
useACMEHost = lib.Sapana.getDomainFromURI cfg.url;
|
2024-07-12 18:11:26 +00:00
|
|
|
forceSSL = true;
|
|
|
|
locations."/" = {
|
2024-10-05 19:49:27 +00:00
|
|
|
proxyPass = "http://127.0.0.1:8096";
|
2024-07-12 18:11:26 +00:00
|
|
|
proxyWebsockets = true;
|
|
|
|
extraConfig = ''
|
|
|
|
# Taken from https://jellyfin.org/docs/general/networking/nginx/
|
|
|
|
client_max_body_size 20M;
|
|
|
|
|
|
|
|
# Security / XSS Mitigation Headers
|
|
|
|
# NOTE: X-Frame-Options may cause issues with the webOS app
|
|
|
|
add_header X-Frame-Options "SAMEORIGIN";
|
|
|
|
add_header X-Content-Type-Options "nosniff";
|
|
|
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
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-Protocol $scheme;
|
|
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
|
|
|
|
|
|
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
|
|
|
|
proxy_buffering off;
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
locations."/socket" = {
|
2024-10-05 19:49:27 +00:00
|
|
|
proxyPass = "http://127.0.0.1:8096";
|
2024-07-12 18:11:26 +00:00
|
|
|
proxyWebsockets = true;
|
|
|
|
extraConfig = ''
|
|
|
|
# Proxy Jellyfin Websockets traffic
|
|
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
|
|
proxy_set_header Connection "upgrade";
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
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-Protocol $scheme;
|
|
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
2024-10-05 19:49:27 +00:00
|
|
|
|
|
|
|
jellyfin = {
|
|
|
|
enable = true;
|
|
|
|
dataDir = cfg.home;
|
|
|
|
group = "media";
|
|
|
|
package = jellyfin-audio-save;
|
|
|
|
};
|
2024-07-12 18:11:26 +00:00
|
|
|
};
|
|
|
|
|
2024-08-29 15:59:28 +00:00
|
|
|
systemd.services = {
|
2024-11-03 19:44:02 +00:00
|
|
|
jellyfin = {
|
|
|
|
# Install packages for plugins
|
|
|
|
path = with pkgs; [
|
|
|
|
id3v2
|
|
|
|
yt-dlp
|
|
|
|
];
|
|
|
|
unitConfig.RequiresMountsFor = cfg.home;
|
|
|
|
};
|
2024-08-29 15:59:28 +00:00
|
|
|
nginx.wants = [ config.systemd.services.jellyfin.name ];
|
|
|
|
};
|
2024-11-03 19:44:02 +00:00
|
|
|
|
|
|
|
# Set permissions for media folders
|
|
|
|
systemd.tmpfiles.rules = [ "Z /storage/Media 6775 aires media - -" ];
|
2024-07-12 18:11:26 +00:00
|
|
|
};
|
|
|
|
}
|