{ config, ... }: let domain = "mjallen.dev"; authUrl = "http://10.0.1.18:9000/outpost.goauthentik.io"; 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.52:5055"; hassUrl = "http://jallen-hass.local:8123"; openWebUIUrl = "http://10.0.1.18:8888"; paperlessUrl = "http://10.0.1.20:28981"; cacheUrl = "http://10.0.1.18:5000"; 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"; }; metrics = { address = ":8082"; # Port for metrics }; }; log = { level = "INFO"; }; metrics = { prometheus = { entryPoint = "metrics"; addEntryPointsLabels = true; addServicesLabels = true; buckets = [0.1 0.3 1.2 5.0]; # Response time buckets }; }; 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 = "http://10.0.1.18:9000/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" ]; }; }; onlyoffice-websocket = { headers.customrequestheaders = { X-Forwarded-Proto = "https"; }; }; # test-errors = { # errors = { # status = [ # "500" # "501" # "503" # "505-599" # ]; # service = # }; # } }; services = { auth.loadBalancer.servers = [ { url = authUrl; } ]; 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; } ]; hass.loadBalancer.servers = [ { url = hassUrl; } ]; chat.loadBalancer.servers = [ { url = openWebUIUrl; } ]; cache.loadBalancer.servers = [ { url = cacheUrl; } ]; paperless.loadBalancer.servers = [ { url = paperlessUrl; } ]; }; routers = { auth = { entryPoints = [ "websecure" ]; rule = "HostRegexp(`{subdomain:[a-z]+}.mjallen.dev`) && PathPrefix(`/outpost.goauthentik.io/`)"; service = "auth"; priority = 15; tls.certResolver = "letsencrypt"; }; authentik = { entryPoints = [ "websecure" ]; rule = "Host(`authentik.${domain}`)"; service = "authentik"; tls.certResolver = "letsencrypt"; }; collabora = { entryPoints = [ "websecure" ]; rule = "Host(`office.${domain}`)"; service = "collabora"; middlewares = "onlyoffice-websocket"; 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"; }; hass = { entryPoints = [ "websecure" ]; rule = "Host(`hass.${domain}`)"; service = "hass"; middlewares = "authentik"; priority = 10; tls.certResolver = "letsencrypt"; }; open-webui = { entryPoints = [ "websecure" ]; rule = "Host(`chat.${domain}`)"; service = "chat"; # middlewares = [ "authentik" ]; priority = 10; tls.certResolver = "letsencrypt"; }; cache = { entryPoints = [ "websecure" ]; rule = "Host(`cache.${domain}`)"; service = "cache"; tls.certResolver = "letsencrypt"; }; # paperless = { # entryPoints = ["websecure"]; # rule = "Host(`paperless.${domain}`)"; # service = "paperless"; # tls.certResolver = "letsencrypt"; # }; }; }; }; }; # todo: fail2ban/etc }