My Nix Configuration

[marvin.services] Add jellyfin-exporter service and config

pyrox.dev 31a6380d 09345ac1

verified
Changed files
+114 -6
lib
systems
x86_64-linux
marvin
prefect
services
+1
lib/data/services.toml
···
host = "marvin"
extUrl = "media.pyrox.dev"
anubis = 8404
+
exporter = 30103
[matrix-server]
port = 6922
+48
systems/x86_64-linux/marvin/services/jellyfin.nix
···
+
{
+
pkgs,
+
lib,
+
config,
+
...
+
}:
{
services.jellyfin = {
enable = true;
···
job_name = "jellyfin_server";
static_configs = [ { targets = [ "127.0.0.1:8096" ]; } ];
}
+
{
+
job_name = "jellyfin";
+
static_configs = [ { targets = [ "127.0.0.1:30103" ]; } ];
+
}
];
+
systemd.services.jellyfin-exporter = lib.mkIf config.services.jellyfin.enable {
+
enable = true;
+
wantedBy = [ "multi-user.target" ];
+
after = [
+
"network.target"
+
"jellyfin.service"
+
];
+
description = "Jellyfin Metrics Exporter for Prometheus";
+
serviceConfig = {
+
ExecStart = "${lib.getExe pkgs.py.jellyfin-exporter} @${config.age.secrets.jellyfin-exporter-config.path}";
+
ReadOnlyPaths = [ config.age.secrets.jellyfin-exporter-config.path ];
+
Restart = "always";
+
DynamicUser = true;
+
User = "jellyfin-exporter";
+
Group = "jellyfin-exporter";
+
StateDirectory = "jellyfin-exporter";
+
CacheDirectory = "stalwart-mail";
+
+
# Hardening
+
MemoryDenyWriteExecute = true;
+
PrivateDevices = true;
+
PrivateTmp = true;
+
ProtectClock = true;
+
ProtectControlGroups = true;
+
ProtectHome = true;
+
ProtectHostname = true;
+
ProtectKernelLogs = true;
+
ProtectKernelModules = true;
+
ProtectKernelTunables = true;
+
RestrictNamespaces = true;
+
RestrictRealtime = true;
+
RestrictSUIDSGID = true;
+
};
+
};
+
age.secrets.jellyfin-exporter-config = {
+
file = ./secrets/jellyfin-exporter-config.age;
+
mode = "444";
+
};
}
+19
systems/x86_64-linux/marvin/services/secrets/jellyfin-exporter-config.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 iqBxIA TYkyDIP1q7bJrSI0YsLBg1F78NF0AnWGTDBL5EdkexI
+
wPDeCC6nUE2Y0xzepEc3p5DM4W5VmXgoUQ7Lxe7pEf4
+
-> ssh-rsa fFaiTA
+
OAT8CyT8DHsr5gkiqhaP5eg//9BAiIGFbiYtr3Wyj3gRv91qsjtRh+MKggqysSPk
+
EN0z7NeoVujFe1mF3/dIFrQD5rcyVSomOnGytmL6R1aSDP677S0JoXUi1RaYfyYq
+
NE59VXK27kCTwsnsD3F2Aish+xmYvBTmUSHDXU/DtKGRB7vgqRSBlMUC9nHCKYvn
+
9dBC7gzikMRBNJ7ciOLfB1m7cR3A31gw+4OpUYqlLXCvfdCuh5QPhToy4VDPFZOq
+
5C4upvtK1qcyy8ZBLL1mwfLpP79t9NIHZnbg0q5fNwSqUkmGfV+mAJHKH5bZMbxB
+
5soPF9yV3mXqXbhl4xEhOMVd50LJwE8t/CyWqkLmZ8CmQ1UovsI4qIDEXP3tLSmC
+
PAT/RYqw84Pzb7Yd8RYELWnbWR/4BbzjkR5rbj7sklSo55be+A0N5YoWuU1ApBR8
+
8LKCKJMzaWnfHS6WNeMNHHP+j7SlBlKnqJWjbjfURJG1HyRx8TIJZ40jZUzfeFG1
+
W4U0RFQZ83d6vz4MBLa9Fk0ms6NyJoO+Rgh0Wl45tritHtkkwYWyxxPL2yPivQ/w
+
NDtBn08eliJzxhAGz0pAHETU8aHgNkLAXbMGku9U/hDaQ4XjGH3np6WOjwnCxJ0W
+
W7ChuMLXcD7CopjGkJSwTUQB3W1McVLQ34yfD7ZroJM
+
-> ssh-ed25519 wpmdHA JpxYf1dtrdlZEx4E8Su0scbGteAREMlKJ3OHfqDWyRc
+
/ZVDz4HSKPT6OyeryIEkfplDLN2XIWm0b4ncg/xezfs
+
--- oY4WmthKy5Ytp1j3hd81DRGFW1A2818Wr9pYmc14hRU
+
�;�2����}�O3h�u5�� ��缻�N��s}oVU���@��嬝��L�at��8�x��P�R��d�Rx{3�b��?o����x8`��V ܬ�"*����e�� #NV��?� ��aP��N��Iɥ�j��S��y3�i����hgп\�D�b��1;��\A<d��f9����A�g�J4؞��R����'תs�COCs� ���ŒN�v�"��vk>8,�DR���
+1
systems/x86_64-linux/marvin/services/secrets/secrets.nix
···
"grafana-smtp-password.age".publicKeys = marvinDefault;
"iceshrimp-secret-config.age".publicKeys = marvinDefault;
"iceshrimp-db-password.age".publicKeys = marvinDefault;
+
"jellyfin-exporter-config.age".publicKeys = marvinDefault;
"minio-root.age".publicKeys = marvinDefault;
"miniflux-admin.age".publicKeys = marvinDefault;
"../nextcloud/nextcloud-admin-pw.age".publicKeys = marvinDefault;
+45 -6
systems/x86_64-linux/prefect/services/caddy.nix
···
{ pkgs, lib, ... }:
let
pns = lib.py.data.services;
+
mail = lib.py.data.mail;
marvin = "http://${lib.py.data.hosts.marvin.ts.ip4}";
+
marvinIP = lib.py.data.hosts.marvin.ts.ip4;
tsNet = lib.py.data.tsNet;
in
{
···
"github.com/caddy-dns/desec@v1.0.1"
"github.com/greenpau/caddy-security@v1.1.31"
"github.com/tailscale/caddy-tailscale@v0.0.0-20250207163903-69a970c84556"
+
"github.com/mholt/caddy-l4@v0.0.0-20250428144642-57989befb7e6"
+
"github.com/mohammed90/caddy-git-fs@v0.0.0-20240805164056-529acecd1830"
];
-
hash = "sha256-lsceZXoTPJCDjl84OQTZUTBRuVAxo8KMWjTXzCFwA6U=";
+
hash = "sha256-NPMrt7hARdnXP3xh4TRsc+TMpuXZzwY6zdrTw6E3nSM=";
};
email = "pyrox@pyrox.dev";
virtualHosts = {
-
# Just get TLS certs for mailserver
-
"mail.pyrox.dev" = { };
# Redirect old domains -> pyrox.dev
"blog.pyrox.dev" = {
serverAliases = [
···
-Server
}
file_server {
-
root /var/www/blog
+
fs blog-repo
hide .git
precompressed br gzip
}
···
header Access-Control-Allow-Origin *
header /.well-known/openpgpkey/{labels.1}.{labels.0}/hu/* Content-Type application/octet-stream
file_server {
-
root /var/www/blog/
+
fs blog-repo
}
'';
};
···
reverse_proxy ${marvin}:${toString pns.pinchflat.port}
'';
};
-
+
"mail.pyrox.dev:80" = {
+
extraConfig = ''
+
reverse_proxy ${marvin}:${mail.intHTTP}
+
'';
+
};
};
+
# Mail Config
+
extraConfig = ''
+
filesystem blog-repo git ${marvin}:${pns.git.port}/pyrox/new-blog {
+
ref pages
+
refresh_period 10m
+
}
+
layer4 {
+
0.0.0.0:465 {
+
route {
+
proxy {
+
proxy_protocol v2
+
upstream ${marvinIP}:${mail.intSMTPS}
+
}
+
}
+
}
+
0.0.0.0:993 {
+
route {
+
proxy {
+
proxy_protocol v2
+
upstream ${marvinIP}:${mail.intIMAPS}
+
}
+
}
+
}
+
0.0.0.0:4190 {
+
route {
+
proxy {
+
proxy_protocol v2
+
upstream ${marvinIP}:${mail.intManageSieve}
+
}
+
}
+
}
+
}
+
'';
};
systemd.services.caddy.serviceConfig.CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
systemd.services.caddy.serviceConfig.AmbientCapabilities = "CAP_NET_BIND_SERVICE";