nix-config/modules/traefik.nix
JuliusFreudenberger 81f4554dd7 Add dependencies between netbird and traefik containers
When setting the explicit ip of the traefik container in the webproxy
network, this resolves the ip of the traefik container changing between
restarts.
2026-04-27 23:09:34 +02:00

135 lines
4.4 KiB
Nix

{
pkgs,
config,
lib,
...
}:
let
cfg = config.services.traefik-docker;
version = "3.6.14";
in {
options.services.traefik-docker = {
enable = lib.mkEnableOption "traefik web server hosted as OCI container";
dashboardUrl = lib.mkOption {
description = "External URL the traefik dashboard will be reachable from, without protocol";
type = lib.types.str;
};
dnsSecrets = lib.mkOption {
description = "Secrets for DNS providers.";
type = lib.types.listOf lib.types.anything;
};
dnsChallengeProvider = lib.mkOption {
description = "Name of provider for DNS challenge.";
type = lib.types.str;
};
};
config = lib.mkIf cfg.enable {
virtualisation.oci-containers.containers = {
traefik = {
image = "traefik:v${version}";
cmd = [
"--providers.docker=true"
"--providers.docker.endpoint=http://docker-socket-proxy:2375"
"--providers.docker.exposedByDefault=false"
"--providers.docker.network=webproxy"
"--providers.file.directory=/dynamic-config"
"--log.level=INFO"
"--api=true"
"--ping=true"
"--entrypoints.web.address=:80"
"--entrypoints.websecure.address=:443"
"--entrypoints.websecure.transport.respondingTimeouts.readTimeout=0"
"--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=0"
"--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=0"
"--serverstransport.forwardingtimeouts.responseheadertimeout=0s"
"--serverstransport.forwardingtimeouts.idleconntimeout=0s"
"--entrypoints.web.http.redirections.entrypoint.to=websecure"
"--entrypoints.websecure.asDefault=true"
"--entrypoints.websecure.http.tls.certresolver=letsencrypt"
"--certificatesresolvers.letsencrypt.acme.email=contact@jfreudenberger.de"
"--certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json"
"--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
"--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=${cfg.dnsChallengeProvider}"
"--providers.file.filename=/dynamic-config/providers.yaml"
];
autoStart = true;
ports = [
"80:80"
"443:443"
];
networks = [
"webproxy"
"docker-socket"
];
environmentFiles = lib.forEach cfg.dnsSecrets (secret: secret.path);
volumes = let
traefik-providers-config = (pkgs.formats.yaml {}).generate "traefik-providers-config" {
tcp.serversTransports.pp-v2.proxyProtocol.version = 2;
};
in [
"/var/run/docker.sock:/var/run/docker.sock"
"${traefik-providers-config}:/dynamic-config/providers.yaml:ro"
];
extraOptions = [
''--mount=type=volume,source=certs,target=/certs,volume-driver=local''
"--ip=172.18.0.2"
"--add-host=host.docker.internal:host-gateway"
"--health-cmd=wget --spider --quiet http://localhost:8080/ping"
"--health-interval=10s"
"--health-timeout=5s"
"--health-retries=3"
"--health-start-period=5s"
];
};
docker-socket-proxy = {
image = "tecnativa/docker-socket-proxy:v0.4.2";
autoStart = true;
networks = [
"docker-socket"
];
environment = {
CONTAINERS = "1";
};
volumes = [
"/var/run/docker.sock:/var/run/docker.sock:ro"
];
};
};
systemd.services."docker-traefik" = {
after = [
"docker-network-webproxy.service"
"docker-network-docker-socket.service"
];
requires = [
"docker-network-webproxy.service"
"docker-network-docker-socket.service"
];
};
systemd.services."docker-network-webproxy" = {
path = [ pkgs.docker ];
serviceConfig = {
Type = "oneshot";
};
script = ''
docker network inspect webproxy || docker network create webproxy --ipv4 --ipv6 --subnet=172.18.0.0/16 --gateway=172.18.0.1
'';
};
systemd.services."docker-network-docker-socket" = {
path = [ pkgs.docker ];
serviceConfig = {
Type = "oneshot";
};
script = ''
docker network inspect docker-socket || docker network create docker-socket --ipv4 --ipv6 --subnet=172.19.0.0/16 --gateway=172.19.0.1
'';
};
};
}