1{
2 lib,
3 config,
4 self',
5 ...
6}:
7let
8 cfg = config.services.jellyfin;
9in
10{
11 services.jellyfin = {
12 enable = true;
13 };
14 users.users.jellyfin.extraGroups = [
15 "input"
16 "render"
17 "video"
18 ];
19 networking.firewall.allowedUDPPorts = [
20 1900
21 7359
22 ];
23 services.prometheus.scrapeConfigs = lib.mkIf cfg.enable [
24 {
25 job_name = "jellyfin_server";
26 static_configs = [ { targets = [ "127.0.0.1:8096" ]; } ];
27 }
28 {
29 job_name = "jellyfin";
30 static_configs = [ { targets = [ "127.0.0.1:30103" ]; } ];
31 }
32 ];
33 systemd.services.jellyfin-exporter = lib.mkIf cfg.enable {
34 enable = true;
35 wantedBy = [ "multi-user.target" ];
36 after = [
37 "network.target"
38 "jellyfin.service"
39 ];
40 description = "Jellyfin Metrics Exporter for Prometheus";
41 serviceConfig = {
42 ExecStart = "${lib.getExe self'.packages.jellyfin-exporter} @${config.age.secrets.jellyfin-exporter-config.path}";
43 ReadOnlyPaths = [ config.age.secrets.jellyfin-exporter-config.path ];
44 Restart = "always";
45 DynamicUser = true;
46 User = "jellyfin-exporter";
47 Group = "jellyfin-exporter";
48 StateDirectory = "jellyfin-exporter";
49 CacheDirectory = "stalwart-mail";
50
51 # Hardening
52 MemoryDenyWriteExecute = true;
53 PrivateDevices = true;
54 PrivateTmp = true;
55 ProtectClock = true;
56 ProtectControlGroups = true;
57 ProtectHome = true;
58 ProtectHostname = true;
59 ProtectKernelLogs = true;
60 ProtectKernelModules = true;
61 ProtectKernelTunables = true;
62 RestrictNamespaces = true;
63 RestrictRealtime = true;
64 RestrictSUIDSGID = true;
65 };
66 };
67 age.secrets.jellyfin-exporter-config = lib.mkIf cfg.enable {
68 file = ./secrets/jellyfin-exporter-config.age;
69 mode = "444";
70 };
71}