133 lines
3.4 KiB
Nix
133 lines
3.4 KiB
Nix
{
|
|
name = "Traefik";
|
|
description = ''
|
|
Runs the Traefik reverse proxy.
|
|
'';
|
|
|
|
nixosModule =
|
|
{
|
|
lib,
|
|
pkgs,
|
|
config,
|
|
hosts,
|
|
...
|
|
}:
|
|
with lib;
|
|
{
|
|
options.traefik = {
|
|
wildcardDomains = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [ ];
|
|
};
|
|
};
|
|
|
|
config =
|
|
let
|
|
cfg = config.traefik;
|
|
routes = concatMap (
|
|
hostname:
|
|
concatMap (
|
|
role:
|
|
role.traefikRoutes {
|
|
inherit hostname;
|
|
config = hosts.${hostname}.config;
|
|
}
|
|
) hosts.${hostname}.roles
|
|
) (builtins.attrNames hosts);
|
|
in
|
|
{
|
|
networking.firewall.allowedTCPPorts = [
|
|
80
|
|
443
|
|
];
|
|
|
|
sops.secrets = {
|
|
"traefik/acmeEmail" = {
|
|
owner = "traefik";
|
|
};
|
|
"traefik/CLOUDFLARE_EMAIL" = {
|
|
owner = "traefik";
|
|
};
|
|
"traefik/CLOUDFLARE_DNS_API_TOKEN" = {
|
|
owner = "traefik";
|
|
};
|
|
};
|
|
sops.templates."traefik.env" = {
|
|
owner = "traefik";
|
|
content = ''
|
|
acmeEmail="${config.sops.placeholder."traefik/acmeEmail"}"
|
|
CLOUDFLARE_EMAIL="${config.sops.placeholder."traefik/CLOUDFLARE_EMAIL"}"
|
|
CLOUDFLARE_DNS_API_TOKEN="${config.sops.placeholder."traefik/CLOUDFLARE_DNS_API_TOKEN"}"
|
|
'';
|
|
};
|
|
|
|
services.traefik = {
|
|
enable = true;
|
|
environmentFiles = [
|
|
config.sops.templates."traefik.env".path
|
|
];
|
|
|
|
staticConfigOptions = {
|
|
entryPoints = {
|
|
web = {
|
|
address = ":80";
|
|
|
|
http = {
|
|
redirections = {
|
|
entryPoint = {
|
|
to = "websecure";
|
|
scheme = "https";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
websecure = {
|
|
address = ":443";
|
|
|
|
http.tls = {
|
|
certResolver = "letsencrypt";
|
|
domains = map (domain: {
|
|
main = domain;
|
|
sans = [ "*.${domain}" ];
|
|
}) cfg.wildcardDomains;
|
|
};
|
|
};
|
|
};
|
|
|
|
certificatesResolvers = {
|
|
letsencrypt = {
|
|
acme = {
|
|
email = "$acmeEmail";
|
|
storage = "/run/traefik/acme.json";
|
|
dnsChallenge = {
|
|
provider = "cloudflare";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
http = {
|
|
routers = listToAttrs (
|
|
map (route: {
|
|
name = route.name;
|
|
value = {
|
|
entrypoints = [ "websecure" ];
|
|
service = route.name;
|
|
rule = route.rule;
|
|
};
|
|
}) routes
|
|
);
|
|
services = listToAttrs (
|
|
map (route: {
|
|
name = route.name;
|
|
value.loadBalancer.servers.url = [ route.target ];
|
|
}) routes
|
|
);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|