Skip to main content
DNZ and a Traefik can start together from one docker-compose.yml and be connected from the first start. Nothing is set up in the dashboard:
  • DNZ’s environment declares the proxy, with a token you pick. The same token goes into Traefik’s configuration, so Traefik connects from wherever it calls, without the connect key or an approval.
  • DNZ_ZONES makes the zone at the first start.
  • Records from Traefik’s routers is turned on, so every container with Traefik labels gets its DNS record from DNZ.
  • Traefik gets its certificates itself, here a Let’s Encrypt wildcard through Cloudflare DNS-01.
The example below is split-horizon: the domain stays on Cloudflare, devices on your LAN resolve *.home.example.com through DNZ to Traefik, and Cloudflare is only used for the certificate. The same file is in the repository as deploy/traefik-stack/docker-compose.yml.

The file

Replace the values marked CHANGE. Make the proxy token with:
and put the same value in both places.
docker-compose.yml
Then point the LAN’s devices (or the router’s DHCP) at this host for DNS. See Pointing clients at DNZ.

What happens at start

1

DNZ sets itself up

DNZ creates the admin, makes home.example.com and adds the proxy edge: approved, recognized by the token, with Traefik’s API and records from its routers turned on.
2

Traefik connects

Traefik waits until DNZ is healthy, then polls DNZ with the token and gets the routers set up in DNZ. The proxy’s card under Proxy shows it connected, with a from environment badge.
3

Containers get their records

Every 30 seconds DNZ reads Traefik’s routers. whoami.home.example.com and dnz.home.example.com get A records pointing at 192.168.1.10.
4

Traefik gets the certificate

Traefik asks Let’s Encrypt for one wildcard certificate for *.home.example.com through Cloudflare DNS-01. Every new container is covered by it, so no request per container.
Open the dashboard at https://dnz.home.example.com and sign in as admin with the password from the file. DNZ asks for a new one.

Things to get right

On the LAN, DNZ answers for the whole zone. Give it home.example.com, not example.com, or names that only exist on Cloudflare stop resolving on the LAN.
--certificatesresolvers.le.acme.dnschallenge.resolvers=1.1.1.1:53,1.0.0.1:53 makes Traefik check the TXT record on public resolvers. Without it, Traefik may ask DNZ, which doesn’t have the challenge, and the certificate fails.
--entrypoints.websecure.http.tls.certresolver=le gives every router on websecure its certificate, DNZ’s and the labels’ alike, so none has to name it. DNZ_PROXY_SEED_CERT_RESOLVER can also set the resolver of DNZ’s own routers.
Compose can’t join a YAML anchor with the Bearer prefix, so the token is written twice. To keep it out of the file, use ${EDGE_TOKEN} in both places and set EDGE_TOKEN in the shell that runs docker compose.
When DNZ itself answers the internet for the domain, the challenge record goes into DNZ instead of Cloudflare: use lego’s httpreq provider against DNZ. See ACME DNS-01.

The settings

DNZ_ZONES names zones, comma-separated, that DNZ makes at start when they don’t exist yet, in the first division. They are never changed or deleted after that. DNZ_PROXY_SEED_* declares one Traefik, Caddy or DNZ Proxy. DNZ writes it at every start: it adds it when there is no proxy of that name, else it writes the fields that are set over the one there. A wrong value stops DNZ at start with the setting’s name, so it never runs half set up. In a cluster, give every node the same settings.

In the dashboard

The fields the environment sets are read-only in the dashboard, the API and the CLI. The proxy’s card says from environment, the edit form greys those fields out, and the proxy can’t be deleted or get another token there. Fields the environment leaves alone (HTTPS redirect, health checks, the Traefik API’s password, …) stay editable, and so do routers, services and middlewares. To manage the proxy in the dashboard again, remove the DNZ_PROXY_SEED_* settings and restart. The proxy stays as it is.