97 lines
2.8 KiB
Nix
97 lines
2.8 KiB
Nix
# Traefik for the test swarm (M1). Runs as a swarm service on the `proxy` overlay so it can
|
|
# reach recipe service VIPs (a host process couldn't). TLS terminates here using the operator's
|
|
# pre-issued wildcard cert via the file provider — NO ACME for commoninternet.net (§4.0).
|
|
# Recipe routers only need `traefik.enable=true` + a Host(...) rule + tls=true; the default
|
|
# certificate (the wildcard) is served for every *.ci.commoninternet.net host.
|
|
{ pkgs, ... }:
|
|
let
|
|
# Static config. Docker *Swarm* provider (v3) + file provider for the cert.
|
|
staticCfg = pkgs.writeText "traefik.yml" ''
|
|
entryPoints:
|
|
web:
|
|
address: ":80"
|
|
websecure:
|
|
address: ":443"
|
|
providers:
|
|
swarm:
|
|
endpoint: "unix:///var/run/docker.sock"
|
|
exposedByDefault: false
|
|
network: proxy
|
|
file:
|
|
directory: /etc/traefik/dynamic
|
|
watch: true
|
|
log:
|
|
level: INFO
|
|
accessLog: {}
|
|
api:
|
|
dashboard: false
|
|
ping: {}
|
|
'';
|
|
|
|
# Dynamic config: serve the pre-issued wildcard as the DEFAULT certificate, so any
|
|
# *.ci.commoninternet.net router with tls=true is covered without a cert resolver.
|
|
certsCfg = pkgs.writeText "certs.yml" ''
|
|
tls:
|
|
stores:
|
|
default:
|
|
defaultCertificate:
|
|
certFile: /var/lib/ci-certs/live/fullchain.pem
|
|
keyFile: /var/lib/ci-certs/live/privkey.pem
|
|
certificates:
|
|
- certFile: /var/lib/ci-certs/live/fullchain.pem
|
|
keyFile: /var/lib/ci-certs/live/privkey.pem
|
|
'';
|
|
|
|
stack = pkgs.writeText "traefik-stack.yml" ''
|
|
version: "3.8"
|
|
services:
|
|
traefik:
|
|
image: traefik:v3.3
|
|
ports:
|
|
- target: 80
|
|
published: 80
|
|
mode: host
|
|
- target: 443
|
|
published: 443
|
|
mode: host
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- /var/lib/ci-certs/live:/var/lib/ci-certs/live:ro
|
|
- ${staticCfg}:/etc/traefik/traefik.yml:ro
|
|
- ${certsCfg}:/etc/traefik/dynamic/certs.yml:ro
|
|
networks:
|
|
- proxy
|
|
deploy:
|
|
mode: replicated
|
|
replicas: 1
|
|
placement:
|
|
constraints:
|
|
- node.role == manager
|
|
restart_policy:
|
|
condition: any
|
|
networks:
|
|
proxy:
|
|
external: true
|
|
'';
|
|
in
|
|
{
|
|
# Gateway forwards 80/443 to cc-ci over the public interface (enp5s0), so open them.
|
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|
|
|
systemd.services.traefik-deploy = {
|
|
description = "Deploy the Traefik swarm stack";
|
|
after = [ "swarm-init.service" ];
|
|
requires = [ "swarm-init.service" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
path = [ pkgs.docker ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
};
|
|
script = ''
|
|
set -eu
|
|
docker stack deploy --detach=true -c ${stack} traefik
|
|
'';
|
|
};
|
|
}
|