127 lines
3.2 KiB
Nix
127 lines
3.2 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
|
||
|
{
|
||
|
sops.secrets = {
|
||
|
"traefik.acmeEmail" = {
|
||
|
owner = "traefik";
|
||
|
format = "dotenv";
|
||
|
};
|
||
|
"traefik.CLOUDFLARE_EMAIL" = {
|
||
|
owner = "traefik";
|
||
|
format = "dotenv";
|
||
|
};
|
||
|
"traefik.CLOUDFLARE_DNS_API_TOKEN" = {
|
||
|
owner = "traefik";
|
||
|
format = "dotenv";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
services.traefik = {
|
||
|
enable = true;
|
||
|
environmentFiles = [
|
||
|
config.sops.secrets."traefik.acmeEmail".path
|
||
|
config.sops.secrets."traefik.CLOUDFLARE_EMAIL".path
|
||
|
config.sops.secrets."traefik.CLOUDFLARE_DNS_API_TOKEN".path
|
||
|
];
|
||
|
|
||
|
staticConfiguration = {
|
||
|
entryPoints = {
|
||
|
web = {
|
||
|
address = ":80";
|
||
|
|
||
|
http = {
|
||
|
redirections = {
|
||
|
entryPoint = {
|
||
|
to = "websecure";
|
||
|
scheme = "https";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
websecure = {
|
||
|
address = ":443";
|
||
|
|
||
|
tls = {
|
||
|
certResolver = "letsencrypt";
|
||
|
domains = mkList (
|
||
|
map (domain: {
|
||
|
main = domain;
|
||
|
sans = [ "*.${domain}" ];
|
||
|
}) cfg.wildcardDomains
|
||
|
);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
certificatesResolvers = {
|
||
|
letsencrypt = {
|
||
|
acme = {
|
||
|
email = "$acmeEmail";
|
||
|
storage = "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
|
||
|
);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|