{ config, lib, pkgs, ... }: let magentaData = import ../data.secret.nix; dataDir = "/var/lib/traefik"; traefikCfg = config.services.traefik; user = "traefik"; group = "traefik"; dynamicConfigFile = pkgs.runCommand "config.toml" { buildInputs = [ pkgs.remarshal ]; preferLocalBuild = true; } '' remarshal -if json -of toml \ < ${pkgs.writeText "dynamic_config.json" (builtins.toJSON traefikCfg.dynamicConfigOptions)} \ > $out ''; staticConfigFile = pkgs.runCommand "config.toml" { buildInputs = [ pkgs.yj ]; preferLocalBuild = true; } '' yj -jt -i \ < ${ pkgs.writeText "static_config.json" (builtins.toJSON (lib.recursiveUpdate traefikCfg.staticConfigOptions { providers.file.filename = "${dynamicConfigFile}"; })) } \ > $out ''; mirrorVolume = path: "${path}:${path}"; in { networking.firewall.allowedTCPPorts = [ 80 443 8080 ]; users.users.${user} = { isSystemUser = true; createHome = true; home = dataDir; inherit group; }; users.groups.${group} = { }; users.groups.docker.members = [ user ]; systemd.tmpfiles.rules = [ "d '${dataDir}' 0700 ${user} ${group} - -" ]; age.secrets.traefik-dashboard-basicauth-users = { file = ../../../secrets/traefik-dashboard-basicauth-users.age; owner = user; inherit group; }; virtualisation.oci-containers = { backend = "docker"; containers.traefik = { image = "traefik:v2.9"; cmd = [ "--configFile=${staticConfigFile}" ]; extraOptions = [ # enable host.docker.internal "--add-host=host.docker.internal:host-gateway" # attach to overlay network. To create, run the following command: # docker network create --driver=overlay --attachable traefik_public "--network=traefik_public" ]; ports = [ "80:80" "443:443" "8080:8080" ]; volumes = [ "${mirrorVolume "/var/run/docker.sock"}:ro" "${mirrorVolume dataDir}" "${mirrorVolume staticConfigFile}:ro" "${mirrorVolume dynamicConfigFile}:ro" "${mirrorVolume config.age.secrets.traefik-dashboard-basicauth-users.path}:ro" ]; }; }; services.traefik = { staticConfigOptions = { entryPoints = { http = { address = ":80"; http.redirections.entryPoint = { to = "https"; scheme = "https"; }; }; https.address = ":443"; dashboard.address = ":8080"; }; api = { }; log = { }; accessLog = { }; certificatesResolvers.le.acme = { storage = "${dataDir}/acme.json"; email = "dmitriy@pleshevski.ru"; tlschallenge = true; }; providers.docker = { network = "traefik_public"; constraints = "Label(`traefik.constraint-label`, `${config.networking.hostName}_public`)"; exposedByDefault = false; swarmMode = true; }; }; dynamicConfigOptions.http = { routers.to_traefik_dashboard = { rule = "Host(`${magentaData.addr}`)"; entryPoints = [ "dashboard" ]; middlewares = [ "traefik_dashboard_auth" ]; service = "api@internal"; }; middlewares = { traefik_dashboard_auth.basicAuth = { usersFile = config.age.secrets.traefik-dashboard-basicauth-users.path; }; }; }; }; }