{config, lib, ... }: let mkRoute = { name, host, port, ip }: { routers = { "${name}" = { rule = "Host(`${name}.${host}`)"; tls.certResolver = "cloudflare"; service = name; entrypoints = "web-internal"; }; }; services = { "${name}".loadBalancer.servers = [ { url = "http://${ip}:${toString port}/"; } ]; }; }; routes = [ { name = "desk"; host = "${config.domain}"; port = 8005; ip = config.tailnetIPs.pinix; } { name = "webhook"; host = "${config.domain}"; port = 9000 ; ip = config.tailnetIPs.pinix; } { name = "files"; host = "${config.domain}"; port = 8010 ; ip = config.tailnetIPs.pinix; } { name = "dash"; host = "${config.domain}"; port = 8002 ; ip = config.tailnetIPs.pinix; } { name = "calendar"; host = "${config.domain}"; port = 5002 ; ip = config.tailnetIPs.pinix; } # fastpi { name = "radio"; host = "${config.domain}"; port = 8080 ; ip = config.tailnetIPs.fastpi; } { name = "couchdb"; host = "${config.domain}"; port = 5984 ; ip = config.tailnetIPs.fastpi; } { name = "jellyfin"; host = "${config.domain}"; port = 8096 ; ip = config.tailnetIPs.fastpi; } { name = "navidrome"; host = "${config.domain}"; port = 4533 ; ip = config.tailnetIPs.fastpi; } { name = "obsidian"; host = "${config.domain}"; port = 3011 ; ip = config.tailnetIPs.fastpi; } { name = "quantum"; host = "${config.domain}"; port = 4333 ; ip = config.tailnetIPs.fastpi; } { name = "metadata"; host = "${config.domain}"; port = 5800 ; ip = config.tailnetIPs.fastpi; } ]; combinedHttp = builtins.foldl' (acc: route: lib.recursiveUpdate acc (mkRoute route)) {} routes; in { services.traefik.dynamicConfigOptions.http = combinedHttp; }