Traefik
← Home
Reverse proxy running in the network Swarm stack on PCT 108. Handles all *.carr-family.org traffic from the Cloudflare Tunnel.
- Config:
/mnt/tank/appdata/traefik/traefik.yml - Dynamic routes:
/mnt/tank/appdata/traefik/routes.yml - Certs:
/mnt/tank/appdata/traefik/certs/acme.json - TLS: Cloudflare DNS challenge (
CF_DNS_API_TOKEN_FILEfrom Docker secret) - Entrypoints:
web(80 → 443 redirect),websecure(443) - Trusted IPs:
192.168.2.0/24(LAN),100.64.0.0/10(Tailscale), Cloudflare IP ranges
Two providers:
- Swarm — local Docker socket on PCT 108 (Swarm service labels)
- Docker —
tcp://192.168.2.191:2375for standalone containers on PCT 102 (e.g. Jellyfin)
External access: Cloudflare Tunnel on the Proxmox host → https://192.168.2.82:443. A 504 means the tunnel is up but Traefik (or the backend) is unreachable.
Static Routes (routes.yml)
Used for services not in Docker Swarm. After any edit, force-restart Traefik:
pct exec 108 -- docker service update --force network_traefik
| Host | Backend | Notes |
|---|---|---|
homeassist.carr-family.org |
192.168.2.129:8123 |
Home Assistant VM |
qbittorrent-vpn.carr-family.org |
192.168.2.190:8081 |
via gluetun |
qbittorrent.carr-family.org |
192.168.2.190:8080 |
lan-only |
ai.carr-family.org |
192.168.2.81:3000 |
PCT 107 |
gcjobs.carr-family.org |
192.168.2.81:8501 |
PCT 107 |
gcjobs-filler.carr-family.org |
192.168.2.81:8000 |
PCT 107, no Authentik |
jellyfin.carr-family.org |
192.168.2.191:8096 |
PCT 101 standalone |
qui.carr-family.org |
192.168.2.190:7476 |
PCT 101 |
n8n.carr-family.org |
192.168.2.83:5678 |
lan-only |
litellm.carr-family.org |
192.168.2.83:4000 |
lan-only |
openclaw.carr-family.org |
192.168.2.83:18789 |
lan-only |
odysseus.carr-family.org |
192.168.2.83:7000 |
lan-only |
otterwiki.carr-family.org |
192.168.2.105:8081 |
PCT 104 standalone |
pterodactyl.carr-family.org |
192.168.2.136:80 |
lan-only |
Middlewares
| Name | Purpose |
|---|---|
lan-only |
IP allowlist — LAN (192.168.2.0/24) + Tailscale (100.64.0.0/10) |
auth |
Basic auth via traefik_auth Docker secret |
secure-headers |
HSTS |
authentik |
ForwardAuth → Authentik outpost (removed from routes.yml as of 2026-06-12) |
Cross-provider middleware reference: Middlewares defined in routes.yml (file provider) must be referenced as authentik@file / lan-only@file in Swarm service deploy.labels — plain names default to @swarm and return 404.
Docker Secrets
| Secret | Purpose |
|---|---|
cf_dns_token |
Cloudflare DNS challenge for wildcard TLS |
cf_api_email |
Cloudflare account email |
traefik_auth |
Dashboard basic auth credentials |
routes.yml Edit Gotcha
sed -i creates a new inode; Traefik's bind-mount stays pinned to the old inode and won't see the change. Always write in-place (e.g. tee or python3) and force-restart after any edit:
pct exec 108 -- docker service update --force network_traefik
Authentik ForwardAuth
The Authentik proxy outpost handles ForwardAuth requests. ForwardAuth address:
http://authentik_authentik-proxy:9000/outpost.goauthentik.io/auth/traefik
The outpost also has its own router (authentik-outpost) catching *.carr-family.org paths starting with /outpost.goauthentik.io/ at priority 15, so auth callbacks after login are handled correctly.
To protect a Swarm service, add to its deploy.labels:
- "traefik.http.routers.<name>.middlewares=authentik@file"
To protect a static route in routes.yml, add to the router:
middlewares: - authentik
Note (2026-06-12): authentik middleware definition removed from routes.yml. All static routes are currently unprotected. Swarm services with the label still have it but the middleware is not defined, so it has no effect.
Cloudflare DNS-only (bypasses Traefik entirely)
| Host | IP | Ports | Notes |
|---|---|---|---|
satisfactory.carr-family.org |
174.95.181.77 (public IP) |
TCP+UDP 7777, TCP 8888 | Grey cloud (proxy off); router port forwards → 192.168.2.134. TCP 8888 = ReliableMessaging. Ports 15000/15777 obsolete since Patch 1.0. |
