# Jellyfin Module # # Self-hosted media server (Plex alternative). # For Tier 3 media streaming. # # Usage: # services.jellyfin-managed.enable = true; # services.jellyfin-managed.domain = "media.yourdomain.com"; # services.jellyfin-managed.mediaLibraries = [ "/mnt/media/movies" "/mnt/media/tv" ]; { config, lib, pkgs, ... }: with lib; let cfg = config.services.jellyfin-managed; in { options.services.jellyfin-managed = { enable = mkEnableOption "managed Jellyfin media server"; domain = mkOption { type = types.str; description = "Domain name for Jellyfin."; example = "media.example.com"; }; port = mkOption { type = types.port; default = 8096; description = "HTTP port for Jellyfin."; }; mediaLibraries = mkOption { type = types.listOf types.str; default = []; description = "Paths to media libraries."; example = [ "/mnt/media/movies" "/mnt/media/tv" "/mnt/media/music" ]; }; enableHardwareAcceleration = mkOption { type = types.bool; default = false; description = "Enable hardware transcoding (requires compatible GPU)."; }; openFirewall = mkOption { type = types.bool; default = true; description = "Open firewall for Jellyfin ports."; }; }; config = mkIf cfg.enable { services.jellyfin = { enable = true; openFirewall = cfg.openFirewall; }; # Give jellyfin access to media directories systemd.services.jellyfin.serviceConfig.SupplementaryGroups = [ "render" # For hardware acceleration "video" # For hardware acceleration ]; # Ensure media directories have correct permissions systemd.tmpfiles.rules = map (path: "d ${path} 0755 jellyfin jellyfin -" ) cfg.mediaLibraries; # Hardware acceleration (Intel VAAPI example) hardware.graphics = mkIf cfg.enableHardwareAcceleration { enable = true; extraPackages = with pkgs; [ intel-media-driver # For Intel # nvidia-vaapi-driver # For NVIDIA libva ]; }; # Note: For hardware acceleration, jellyfin user needs access to /dev/dri users.users.jellyfin.extraGroups = mkIf cfg.enableHardwareAcceleration [ "render" "video" ]; # Reverse proxy example # services.caddy.virtualHosts."${cfg.domain}".extraConfig = '' # reverse_proxy localhost:${toString cfg.port} # ''; }; }