134 lines
3.4 KiB
Nix
134 lines
3.4 KiB
Nix
{ 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;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|