{ config, ... }: let traefikDataDir = "/var/lib/traefik"; traefikUserId = config.users.users.nix-apps.uid; traefikGroupId = config.users.groups.jallen-nas.gid; domain = "mjallen.dev"; authentikUrl = "http://10.0.1.18:9000"; collaboraUrl = "http://10.0.1.18:9980"; cloudUrl = "http://10.0.2.18:80"; jellyfinUrl = "http://10.0.1.18:8096"; jellyseerrUrl = "http://10.0.1.18:5055"; in { networking.firewall = { allowedTCPPorts = [ 80 443 8080 ]; allowedUDPPorts = [ 80 443 8080 ]; }; services.traefik = { enable = true; dataDir = "/media/nas/ssd/nix-app-data/traefik"; group = "jallen-nas"; environmentFiles = [ "${config.services.traefik.dataDir}/traefik.env" ]; # todo: sops staticConfigOptions = { entryPoints = { web = { address = ":80"; asDefault = true; http.redirections.entrypoint = { to = "websecure"; scheme = "https"; }; }; websecure = { address = ":443"; asDefault = true; http.tls.certResolver = "letsencrypt"; }; }; log = { level = "INFO"; }; certificatesResolvers.letsencrypt.acme = { email = "jalle008@proton.me"; storage = "${config.services.traefik.dataDir}/acme.json"; dnsChallenge = { provider = "cloudflare"; resolvers = [ "1.1.1.1:53" "8.8.8.8:53" ]; }; }; api.dashboard = true; # Access the Traefik dashboard on :8080 of your server # api.insecure = true; }; dynamicConfigOptions = { http = { middlewares = { authentik = { forwardAuth = { tls.insecureSkipVerify = true; address = "https://authentik.${domain}/outpost.goauthentik.io/auth/traefik"; trustForwardHeader = true; authResponseHeaders = [ "X-authentik-username" "X-authentik-groups" "X-authentik-email" "X-authentik-name" "X-authentik-uid" "X-authentik-jwt" "X-authentik-meta-jwks" "X-authentik-meta-outpost" "X-authentik-meta-provider" "X-authentik-meta-app" "X-authentik-meta-version" ]; }; }; }; services = { authentik.loadBalancer.servers = [ { url = authentikUrl; } ]; collabora.loadBalancer.servers = [ { url = collaboraUrl; } ]; cloud.loadBalancer.servers = [ { url = cloudUrl; } ]; jellyfin.loadBalancer.servers = [ { url = jellyfinUrl; } ]; jellyseerr.loadBalancer.servers = [ { url = jellyseerrUrl; } ]; }; routers = { authentik = { entryPoints = ["websecure"]; rule = "Host(`authentik.${domain}`)"; service = "authentik"; tls.certResolver = "letsencrypt"; }; collabora = { entryPoints = ["websecure"]; rule = "Host(`office.${domain}`)"; service = "collabora"; tls.certResolver = "letsencrypt"; }; cloud = { entryPoints = ["websecure"]; rule = "Host(`cloud.${domain}`)"; service = "cloud"; tls.certResolver = "letsencrypt"; }; jellyfin = { entryPoints = ["websecure"]; rule = "Host(`jellyfin.${domain}`)"; service = "jellyfin"; tls.certResolver = "letsencrypt"; }; jellyseerr = { entryPoints = ["websecure"]; rule = "Host(`jellyseerr.${domain}`)"; service = "jellyseerr"; tls.certResolver = "letsencrypt"; }; }; }; }; }; # todo: fail2ban/etc }