homelab/modules/nixos/services/jellyfin.nix
plasmagoat bcbcc8b17b
Some checks failed
Test / tests (push) Has been cancelled
/ OpenTofu (push) Has been cancelled
homelab framework module init (everything is a mess)
2025-07-28 02:05:13 +02:00

125 lines
3 KiB
Nix

# modules/services/jellyfin.nix
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.jellyfin;
in {
options.services.jellyfin = {
enable = mkEnableOption "Jellyfin media server";
port = mkOption {
type = types.port;
default = 8096;
description = "Port for Jellyfin web interface";
};
dataDir = mkOption {
type = types.str;
default = "/var/lib/jellyfin";
description = "Directory to store Jellyfin data";
};
mediaDir = mkOption {
type = types.str;
default = "/media";
description = "Directory containing media files";
};
enableMetrics = mkOption {
type = types.bool;
default = true;
description = "Enable Prometheus metrics";
};
exposeWeb = mkOption {
type = types.bool;
default = true;
description = "Expose web interface through reverse proxy";
};
};
config = mkIf cfg.enable {
# Enable the service
services.jellyfin = {
enable = true;
dataDir = cfg.dataDir;
};
# Configure global settings
homelab.global = {
# Add backup job for Jellyfin data
backups.jobs = [
{
name = "jellyfin-config";
backend = "restic";
paths = ["${cfg.dataDir}/config" "${cfg.dataDir}/data"];
schedule = "0 2 * * *"; # Daily at 2 AM
excludePatterns = [
"*/cache/*"
"*/transcodes/*"
"*/logs/*"
];
preHook = ''
# Stop jellyfin for consistent backup
systemctl stop jellyfin
'';
postHook = ''
# Restart jellyfin after backup
systemctl start jellyfin
'';
}
{
name = "jellyfin-media";
backend = "restic";
paths = [cfg.mediaDir];
schedule = "0 3 * * 0"; # Weekly on Sunday at 3 AM
excludePatterns = [
"*.tmp"
"*/.@__thumb/*" # Synology thumbnails
];
}
];
# Add reverse proxy entry if enabled
reverseProxy.entries = mkIf cfg.exposeWeb [
{
subdomain = "jellyfin";
port = cfg.port;
enableAuth = false; # Jellyfin has its own auth
websockets = true;
customHeaders = {
"X-Forwarded-Proto" = "$scheme";
"X-Forwarded-Host" = "$host";
};
}
];
# Add monitoring endpoint if metrics enabled
monitoring.endpoints = mkIf cfg.enableMetrics [
{
name = "jellyfin";
port = cfg.port;
path = "/metrics"; # Assuming you have a metrics plugin
jobName = "jellyfin";
scrapeInterval = "60s";
labels = {
service = "jellyfin";
type = "media-server";
};
}
];
};
# Open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
# Create media directory
systemd.tmpfiles.rules = [
"d ${cfg.mediaDir} 0755 jellyfin jellyfin -"
];
};
}