{ config, lib, ... }: let cfg = config.local.traefik; traefikCfg = config.services.traefik; in { options.local.traefik = with lib; { enable = mkEnableOption "Enable traefik service"; dashboard = { enable = mkEnableOption "Enable traefik dashboard"; host = mkOption { type = types.nullOr types.str; description = "Traefik dashboard host"; }; }; }; config = lib.mkIf cfg.enable { networking.firewall.allowedTCPPorts = [ 80 443 ] ++ lib.optional cfg.dashboard.enable 8080; services.traefik = { enable = true; staticConfigOptions = { entryPoints = { http = { address = ":80"; http.redirections.entryPoint = { to = "https"; scheme = "https"; }; }; https.address = ":443"; }; log = { }; accessLog = { }; certificatesResolvers.le.acme = { storage = "${traefikCfg.dataDir}/acme.json"; email = "dmitriy@pleshevski.ru"; tlschallenge = true; }; providers.docker = { network = "rp_public"; constraints = "Label(`traefik.constraint-label`, `${config.networking.hostName}_public`)"; exposedByDefault = false; swarmMode = true; }; }; } // lib.mkIf cfg.dashboard.enable { staticConfigOptions = { api = { }; entryPoints.dashboard.address = ":8080"; }; dynamicConfigOptions.http = { routers.to_traefik_dashboard = { rule = "Host(`${cfg.dashboard.host}`)"; entryPoints = [ "dashboard" ]; middlewares = [ "traefik_dashboard_auth" ]; service = "api@internal"; }; middlewares = { traefik_dashboard_auth.basicAuth = { usersFile = config.age.secrets.traefik-dashboard-basicauth-users.path; }; }; }; }; }; }