From 86680f71f38c9d97e0718d733cd1ab5e14fc991d Mon Sep 17 00:00:00 2001 From: Alfredo Di Stasio Date: Tue, 30 Jun 2026 10:47:37 +0200 Subject: [PATCH] refactor: split dynamic config by site --- README.md | 26 ++++++++-- config/dynamic/azionelab.yml | 29 +++++++++++ config/dynamic/lab-younerd.yml | 29 +++++++++++ config/dynamic/tcp-services.yml | 53 -------------------- docs/adr/0001-traefik-tcp-tls-passthrough.md | 2 +- docs/architecture.md | 2 +- docs/deployment.md | 6 ++- docs/operations.md | 4 +- docs/runbook.md | 4 +- 9 files changed, 89 insertions(+), 66 deletions(-) create mode 100644 config/dynamic/azionelab.yml create mode 100644 config/dynamic/lab-younerd.yml delete mode 100644 config/dynamic/tcp-services.yml diff --git a/README.md b/README.md index eb93115..81a88fb 100644 --- a/README.md +++ b/README.md @@ -13,22 +13,38 @@ Docker Compose deployment for Traefik used as a TCP load balancer with TLS passt ## Configuration -Edit SNI routes and backend targets in `config/dynamic/tcp-services.yml`: +Add or edit one file per site under `config/dynamic/`. For example, `config/dynamic/lab-younerd.yml` contains: ```yaml +http: + routers: + lab-younerd-http: + entryPoints: + - web + rule: "Host(`lab.younerd.org`)" + service: lab-younerd-http + + services: + lab-younerd-http: + loadBalancer: + servers: + - url: "http://127.0.0.1:8080" + tcp: routers: - lab-younerd: + lab-younerd-tls: + entryPoints: + - tls rule: "HostSNI(`lab.younerd.org`)" - service: lab-younerd + service: lab-younerd-tls tls: passthrough: true services: - lab-younerd: + lab-younerd-tls: loadBalancer: servers: - - address: "host.docker.internal:8443" + - address: "127.0.0.1:8443" ``` `HostSNI(...)` matches the hostname sent by the client during the TLS handshake. This deployment uses host networking so Traefik can reach services bound to the Docker host loopback address, such as `127.0.0.1:8443`. diff --git a/config/dynamic/azionelab.yml b/config/dynamic/azionelab.yml new file mode 100644 index 0000000..6bef6c0 --- /dev/null +++ b/config/dynamic/azionelab.yml @@ -0,0 +1,29 @@ +http: + routers: + azionelab-http: + entryPoints: + - web + rule: "Host(`azionelab.org`) || Host(`www.azionelab.org`)" + service: azionelab-http + + services: + azionelab-http: + loadBalancer: + servers: + - url: "http://127.0.0.1:9080" + +tcp: + routers: + azionelab-tls: + entryPoints: + - tls + rule: "HostSNI(`azionelab.org`) || HostSNI(`www.azionelab.org`)" + service: azionelab-tls + tls: + passthrough: true + + services: + azionelab-tls: + loadBalancer: + servers: + - address: "127.0.0.1:9443" diff --git a/config/dynamic/lab-younerd.yml b/config/dynamic/lab-younerd.yml new file mode 100644 index 0000000..4c2f81c --- /dev/null +++ b/config/dynamic/lab-younerd.yml @@ -0,0 +1,29 @@ +http: + routers: + lab-younerd-http: + entryPoints: + - web + rule: "Host(`lab.younerd.org`)" + service: lab-younerd-http + + services: + lab-younerd-http: + loadBalancer: + servers: + - url: "http://127.0.0.1:8080" + +tcp: + routers: + lab-younerd-tls: + entryPoints: + - tls + rule: "HostSNI(`lab.younerd.org`)" + service: lab-younerd-tls + tls: + passthrough: true + + services: + lab-younerd-tls: + loadBalancer: + servers: + - address: "127.0.0.1:8443" diff --git a/config/dynamic/tcp-services.yml b/config/dynamic/tcp-services.yml deleted file mode 100644 index bfb714f..0000000 --- a/config/dynamic/tcp-services.yml +++ /dev/null @@ -1,53 +0,0 @@ -http: - routers: - lab-younerd-acme: - entryPoints: - - web - rule: "Host(`lab.younerd.org`)" - service: lab-younerd-acme - - azionelab-acme: - entryPoints: - - web - rule: "Host(`azionelab.org`) || Host(`www.azionelab.org`)" - service: azionelab-acme - - services: - lab-younerd-acme: - loadBalancer: - servers: - - url: "http://127.0.0.1:8080" - - azionelab-acme: - loadBalancer: - servers: - - url: "http://127.0.0.1:9080" - -tcp: - routers: - lab-younerd: - entryPoints: - - tls - rule: "HostSNI(`lab.younerd.org`)" - service: lab-younerd - tls: - passthrough: true - - azionelab: - entryPoints: - - tls - rule: "HostSNI(`azionelab.org`) || HostSNI(`www.azionelab.org`)" - service: azionelab - tls: - passthrough: true - - services: - lab-younerd: - loadBalancer: - servers: - - address: "127.0.0.1:8443" - - azionelab: - loadBalancer: - servers: - - address: "127.0.0.1:9443" diff --git a/docs/adr/0001-traefik-tcp-tls-passthrough.md b/docs/adr/0001-traefik-tcp-tls-passthrough.md index 0e3c63b..1a3b101 100644 --- a/docs/adr/0001-traefik-tcp-tls-passthrough.md +++ b/docs/adr/0001-traefik-tcp-tls-passthrough.md @@ -34,7 +34,7 @@ The container does not mount the Docker socket, does not run privileged, drops L ## Operational impact -Operators update backend IP addresses and ports in `config/dynamic/tcp-services.yml`. Traefik listens directly on host `80/tcp` and `443/tcp`; the ping entrypoint is used by the healthcheck. +Operators update backend IP addresses and ports in per-site files under `config/dynamic/`. Traefik listens directly on host `80/tcp` and `443/tcp`; the ping entrypoint is used by the healthcheck. ## Rollback diff --git a/docs/architecture.md b/docs/architecture.md index 1d48aa1..c41d09e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -6,7 +6,7 @@ This project runs Traefik Proxy as a Dockerized TCP load balancer. - `compose.yaml`: defines the Traefik container, host networking, host-based configuration volume, container hardening, and healthcheck. - `config/traefik.yml`: static Traefik configuration for HTTP, TCP TLS, ping, file provider, and logging. -- `config/dynamic/tcp-services.yml`: dynamic HTTP challenge routers, TCP routers, and backend load-balancer services. +- `config/dynamic/*.yml`: dynamic per-site HTTP routers, TCP routers, and backend load-balancer services. ## Data flow diff --git a/docs/deployment.md b/docs/deployment.md index aea42a2..3ac8474 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -8,7 +8,7 @@ ## Configuration -Update `config/dynamic/tcp-services.yml` with the required SNI hostnames and backend addresses: +Add or update a per-site file under `config/dynamic/` with the required hostnames and backend addresses: ```yaml tcp: @@ -28,7 +28,9 @@ tcp: This deployment uses host networking so Traefik can reach services bound to host loopback addresses such as `127.0.0.1:8443`. -HTTP traffic is routed separately with HTTP `Host(...)` rules on port `80`. Configure the HTTP services in `config/dynamic/tcp-services.yml` to point at the local backend port that should handle redirects and ACME challenge paths. +HTTP traffic is routed separately with HTTP `Host(...)` rules on port `80`. Configure the HTTP service in the same per-site file to point at the local backend port that should handle redirects and ACME challenge paths. + +Keep each site's HTTP and TCP routers in the same dynamic file, for example `config/dynamic/lab-younerd.yml` or `config/dynamic/azionelab.yml`. The `./config` directory is the host-based configuration volume. It is mounted read-only into the container: diff --git a/docs/operations.md b/docs/operations.md index 98d72f3..fe733af 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -46,11 +46,11 @@ docker compose logs -f traefik ## Backend maintenance -To remove a backend from rotation, edit `config/dynamic/tcp-services.yml` and remove or comment out its `address` entry. Keep at least one reachable backend configured before applying the change. +To remove a backend from rotation, edit that site's file under `config/dynamic/` and remove or comment out its `address` entry. Keep at least one reachable backend configured before applying the change. This deployment uses host networking. For backends running on the Docker host, use `127.0.0.1:PORT` when the service is bound to host loopback. -For HTTP on port `80`, update the HTTP services in `config/dynamic/tcp-services.yml` to match the local backend ports that handle redirects and ACME challenge paths. +For HTTP on port `80`, update the HTTP services in the relevant site file under `config/dynamic/` to match the local backend ports that handle redirects and ACME challenge paths. ## Known operational risks diff --git a/docs/runbook.md b/docs/runbook.md index a2e3434..9538096 100644 --- a/docs/runbook.md +++ b/docs/runbook.md @@ -16,7 +16,7 @@ docker compose down ### Update backend targets -1. Edit `config/dynamic/tcp-services.yml`. +1. Edit the relevant site file under `config/dynamic/`. 2. Run `docker compose config` to catch Compose-level errors. 3. Watch Traefik logs: @@ -49,7 +49,7 @@ Check that port `80/tcp` is reachable from the internet and that the matching HT ### Wrong certificate is presented -Because TLS is passed through, the certificate comes from the selected backend. Check backend certificate configuration and SNI routing rules in `config/dynamic/tcp-services.yml`. +Because TLS is passed through, the certificate comes from the selected backend. Check backend certificate configuration and SNI routing rules in the relevant file under `config/dynamic/`. ## Rollback