puzzlevision/modules/nixos/services/traefik/default.nix

110 lines
2.7 KiB
Nix

{
lib,
namespace,
config,
...
}: with lib; with lib.${namespace};
let
cfg = config.${namespace}.services.traefik;
in {
options.${namespace}.services.traefik = {
enable = mkEnableOption "Enable the Traefik service.";
cloudflareEmail = mkOption {
type = types.str;
default = "system@thevoid.cafe";
example = "system@thevoid.cafe";
description = "Specify the E-Mail associated with your Cloudflare account for ACME.";
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [80 8080 443]; # http, dashboard, https
systemd.services.traefik = {
environment = {
CF_API_EMAIL = cfg.cloudflareEmail;
};
serviceConfig = {
EnvironmentFile = [config.sops.secrets."services/cloudflare/api_key".path];
};
};
services.traefik = {
enable = true;
group = "docker";
staticConfigOptions = {
log = {
level = "INFO";
filePath = "/var/lib/traefik/traefik.log";
noColor = false;
maxSize = 100;
compress = true;
};
api = {
dashboard = true;
insecure = true;
};
providers = {
docker = {
exposedByDefault = false;
network = "proxy";
};
};
certificatesResolvers = {
letsencrypt = {
acme = {
email = cfg.cloudflareEmail;
storage = "/var/lib/traefik/acme.json";
#caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"; # Uncomment this when testing stuff!
dnsChallenge = {
provider = "cloudflare";
};
};
};
};
entryPoints.web = {
address = ":80";
http.redirections.entryPoint = {
to = "websecure";
scheme = "https";
permanent = true;
};
};
entryPoints.websecure = {
address = ":443";
http.tls = {
certResolver = "letsencrypt";
domains = [
{
main = "voidtales.dev";
sans = ["*.voidtales.dev"];
}
{
main = "voxtek.enterprises";
sans = ["*.voxtek.enterprises"];
}
{
main = "thevoid.cafe";
sans = ["*.thevoid.cafe" "*.bsky.thevoid.cafe"];
}
{
main = "reckers.dev";
sans = ["*.reckers.dev"];
}
{
main = "rhysbot.co.uk";
sans = ["*.rhysbot.co.uk"];
}
];
};
};
};
};
};
}