Skip to content

traefik-dmz

traefik-dmz is the fleet's public edge, the one place a request from the internet enters. It is traefik-agent with two additions: a replica of the hub's Redis, which gives it every published route, and cloudflared, which opens a tunnel outward to Cloudflare. The internet reaches the fleet through that outbound connection, so no port is forwarded.

It runs on one host, bh01, on the DMZ. See DMZ edge (bh01) for the build.

What it runs

traefik
error-pages
socket-proxy
logrotate
socket-proxy-rw
traefik-kop
redis
cloudflared

The first six are traefik-agent, included whole. See traefik-agent and traefik-basic for what each does.

Service Does
redis A read-only replica of the Redis on tf01. It publishes no port
cloudflared Holds the tunnel open to Cloudflare, and hands each public request to this stack's Traefik

A public request takes this path: Cloudflare, the tunnel, cloudflared, Traefik on bh01, then the route Traefik finds for the hostname. Traefik reads its routes from the local replica, through the Redis provider. See The Redis provider.

The replica means the edge keeps the routes it last saw when tf01 is unreachable.

cloudflared runs as a named tunnel with its settings in a file on the host. The public hostnames it accepts are listed in that file, under ingress, and are not managed in Cloudflare's dashboard.

The containers are named after the project, traefik, as in every Traefik stack. cloudflared's ingress rules depend on that, since each one sends its requests to traefik-traefik.

In bootstrap mode

The stack is a Traefik already, so the run keeps it and adds no stand-in. The run sets TRAEFIK_AUTH_CHAIN to chain-no-auth@file while bh01 is in bootstrap mode. See What it changes.

Values it reads

Key Reads Kind Described under
CF_API_EMAIL CF_API_EMAIL Secret Traefik
CF_DNS_API_TOKEN CF_DNS_API_TOKEN Secret Traefik
LE_EMAIL LE_EMAIL Secret Traefik
CROWDSEC_LAPI_HOST GLOBAL_CROWDSEC_LAPI_HOST Variable Traefik
AUTHENTIK_HOST GLOBAL_AUTHENTIK_HOST Variable Traefik
REDIS_PASSWORD TRAEFIK_KOP_REDIS_PASSWORD Secret Traefik
REDIS_SERVER TRAEFIK_KOP_REDIS_SERVER Secret Traefik

It also reads the 19 operational defaults, as every stack does.

All seven are created before the first host is built. See the Traefik values.

REDIS_SERVER is tf01's name. The replica copies from it, and bh01's traefik-kop publishes to it. REDIS_PASSWORD is the password both use there.

cloudflared reads no Variable and no Secret. Its credential is a file on the host.

What the host needs

The project is traefik, so the stack's folders sit under /opt/docker/volumes/traefik and /opt/docker/logs/traefik. Both are mode 0750, owned by the admin account with group 101000.

Folder Owner Mode
/opt/docker/logs/traefik/traefik 101000:101000 0755
/opt/docker/volumes/traefik/traefik-certs 101000:101000 Default
/opt/docker/volumes/traefik/traefik-plugins 101000:101000 Default
/opt/docker/volumes/traefik/cloudflared-config 101000:101000 Default
/opt/docker/volumes/traefik/cloudflared-secrets 101000:101000 0700

These seed files come from fleet-stacks. Each is written only when nothing is at its path, so a copy already on the host is never replaced.

File Copied from Owner Mode
/opt/docker/volumes/traefik/cloudflared-config/config.yml containers/cloudflared/config/config.yml.example 101000:101000 Default
Port Allowed from Comment
80/tcp Anywhere Traefik HTTP
443/tcp Anywhere Traefik HTTPS
8443/tcp Anywhere Traefik HTTPS (alt)

The host's NixOS configuration creates the folders and the seed files, and opens the ports, when the host is deployed. It reads them from the host's file in the private repo, nixos/hosts/<host>.json, which nixos-sync.yml writes from the stack's setup.yaml. See Host layout.

The run copies the example config.yml, which holds a placeholder for the tunnel's ID. Two things are left to you, because they come from your Cloudflare account: the real ID in that file, and the tunnel's credentials file in cloudflared-secrets. The host page has the steps. See DMZ edge (bh01).

The stack opens no port for Redis. The replica and traefik-kop both connect outward, to port 6379 on tf01.

Hostnames

The dashboard answers on port 8443, under the same two names as in every Traefik stack. See traefik-basic.

Public hostnames are the ones listed under ingress in cloudflared's config.yml. Each needs a DNS record in Cloudflare that points at the tunnel.

Verify

In Komodo, the traefik-dmz Stack shows as running with eight services.

On the host, list the Stack's containers. Komodo names the Compose project after the Stack, not after PROJECT_NAME:

docker compose -p traefik-dmz ps

Every container shows healthy in the STATUS column. cloudflared's check passes only while the tunnel has a connection to Cloudflare, so healthy there means the tunnel is up.

Ask the replica whether it is in step with tf01:

docker exec traefik-redis redis-cli info replication

The output includes these two lines:

role:slave
master_link_status:up

A replica that cannot reach tf01 reports master_link_status:down and goes on serving the routes it has.

Data worth keeping

Folder under /opt/docker/volumes/traefik Holds
traefik-certs acme.json, with the Let's Encrypt account and every certificate issued to it
cloudflared-secrets The tunnel's credentials file. Anyone holding it can serve the tunnel's hostnames
cloudflared-config config.yml, with the tunnel's ID and the public hostnames

Not yet confirmed

  • The stack has not been deployed on any host.
  • The path from bh01 to the Redis on tf01. tf01 opens port 6379 to the internal subnet, and bh01 is on the DMZ. The replica and traefik-kop need a way in on tf01 and on the network's firewall. The host page adds both, and neither has been tried. See Open the path across the boundary.
  • Traefik reading the replica. The stack gives Traefik's Redis provider a password, and the replica asks for none. Redis may refuse a sign-in it did not ask for.
  • The replica's health check. It sends a write, which a read-only replica refuses.
  • The example ingress rule. It sends requests to Traefik's port 80, where every request is redirected to HTTPS. A public request may be redirected without end.
  • cloudflared before the tunnel exists. With the placeholder still in config.yml the container cannot connect, and whether it then keeps the Stack from showing as running has not been tried.