navidrome
Some checks failed
ci/woodpecker/push/build-cache Pipeline failed
ci/woodpecker/cron/dependency-pr Pipeline was successful

This commit is contained in:
Lucy Hochkamp 2025-12-04 00:21:41 +01:00
parent 1408470a53
commit 28dc0896b9
No known key found for this signature in database
16 changed files with 969 additions and 171 deletions

View file

@ -5,61 +5,82 @@
...
}:
let
inherit (lib)
mapAttrsToList
mkMerge
splitString
concatStringsSep
mkIf
mkOption
mkEnableOption
;
inherit (lib.types)
str
bool
nullOr
anything
attrsOf
submodule
listOf
;
cfg = config.xyno.services.traefik;
simpleProxyOpts = lib.mapAttrsToList (
simpleProxyOpts = mapAttrsToList (
n: v:
let
router = "simpleproxy-${n}-router";
service = "simpleproxy-${n}-service";
spl = lib.splitString "." v.host;
certDomain =
if (builtins.length spl) > 2 then lib.concatStringsSep "." (builtins.tail spl) else spl;
router = v.routerName;
service = v.serviceName;
spl = splitString "." v.host;
certDomain = if (builtins.length spl) > 2 then concatStringsSep "." (builtins.tail spl) else spl;
in
{
routers."${router}-robotstxt" = {
service = "robotstxt";
rule = "Host(`${v.host}`) && Path(`/robots.txt`)";
tls.certResolver = "letsencrypt";
tls.domains = [
{
main = certDomain;
sans = [ "*.${certDomain}" ];
}
];
};
routers.${router} = {
inherit service;
rule = "Host(`${v.host}`)";
tls.certResolver = "letsencrypt";
tls.domains = [
{
main = certDomain;
sans = [ "*.${certDomain}" ];
}
];
};
services.${service} = {
loadBalancer.servers = [
{ url = v.internal; }
];
loadBalancer.serverTransport = lib.mkIf (v.transport != null) v.transport;
};
services.robotstxt = {
loadBalancer.servers = [
{ url = "http://127.0.0.2:8080"; }
];
};
}
mkMerge [
(mkIf v.robotProtection {
routers."${router}-robotstxt" = {
service = "robotstxt";
rule = "Host(`${v.host}`) && Path(`/robots.txt`)";
tls.certResolver = "letsencrypt";
tls.domains = [
{
main = certDomain;
sans = [ "*.${certDomain}" ];
}
];
};
services.robotstxt = {
loadBalancer.servers = [
{ url = "http://127.0.0.2:8080"; }
];
};
})
{
routers.${router} = {
inherit service;
inherit (v) middlewares;
rule = if v.rule != null then v.rule else "Host(`${v.host}`)";
tls.certResolver = "letsencrypt";
tls.domains = [
{
main = certDomain;
sans = [ "*.${certDomain}" ];
}
];
};
services.${service} = {
loadBalancer.servers = [
{ url = v.internal; }
];
loadBalancer.serversTransport = mkIf (v.transport != null) v.transport;
};
}
]
) cfg.simpleProxy;
in
{
options.xyno.services.traefik.enable = lib.mkEnableOption "enables traefik";
options.xyno.services.traefik.noBots = lib.mkOption {
type = lib.types.bool;
options.xyno.services.traefik.enable = mkEnableOption "enables traefik";
options.xyno.services.traefik.noBots = mkOption {
type = bool;
default = true;
};
options.xyno.services.traefik.simpleProxy = lib.mkOption {
options.xyno.services.traefik.simpleProxy = mkOption {
example = {
"example" = {
host = "example.org";
@ -68,38 +89,63 @@ in
};
};
default = { };
type = lib.types.attrsOf (
lib.types.submodule {
options = {
middlewares = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
};
internal = lib.mkOption {
type = lib.types.str;
};
host = lib.mkOption {
type = lib.types.str;
};
transport = lib.mkOption {
type = lib.types.nullOr lib.types.anything;
default = null;
};
type = attrsOf (
submodule (
{ config, name,... }:
{
options = {
middlewares = mkOption {
type = listOf str;
default = [];
};
}
};
internal = mkOption {
type = str;
description = "where to proxy to";
};
host = mkOption {
type = str;
description = "used for the route and tls";
};
routerName = mkOption {
type = str;
default = "simpleproxy-${name}-router";
};
serviceName = mkOption {
type = str;
default = "simpleproxy-${name}-service";
};
robotProtection = mkOption {
type = bool;
default = true;
description = "robots.txt and (soon) iocane";
};
rule = mkOption {
type = str;
default = "Host(`${config.host}`)";
description = "overrides the Host(`\${host}`) rule with something custom if set";
};
transport = mkOption {
type = nullOr anything;
default = null;
};
};
}
)
);
};
config = lib.mkIf cfg.enable {
config = mkIf cfg.enable {
services.nginx = {
enable = lib.mkIf cfg.noBots true;
defaultListen = lib.mkIf cfg.noBots [
enable = mkIf cfg.noBots true;
defaultListen = mkIf cfg.noBots [
{
addr = "127.0.0.2";
port = 8080;
}
];
virtualHosts._.default = true;
virtualHosts._.default = true;
virtualHosts._.locations."/".root = pkgs.writeTextFile {
name = "robots.txt";
destination = "/robots.txt";
@ -115,7 +161,8 @@ in
config.sops.templates."traefik.env".path
];
staticConfigOptions = {
metrics = lib.mkIf config.xyno.services.monitoring.enable {
accessLog = {};
metrics = mkIf config.xyno.services.monitoring.enable {
otlp.http.endpoint = "http://localhost:8429/v1/metrics";
};
entryponits.web = {
@ -137,13 +184,16 @@ in
email = "ssl@xyno.systems";
caServer = "https://acme-v02.api.letsencrypt.org/directory";
dnsChallenge = {
resolvers = [ "8.8.8.8" "1.1.1.1" ];
resolvers = [
"8.8.8.8"
"1.1.1.1"
];
provider = "desec";
};
};
};
dynamicConfigOptions = {
http = lib.mkMerge simpleProxyOpts;
http = mkMerge simpleProxyOpts;
# tls.options.default = {
# # mozilla modern
# minVersion = "VersionTLS13";