Traefik Reverse Proxy Infrastructure
Status: Production — Nginx Proxy Manager migration complete
Last reviewed: October 2026
Related: Traefik Standards & Migration
Purpose and architecture
Traefik v3 is the centralized reverse proxy for the BarnesBears home lab. It handles HTTPS termination, Let's Encrypt certificates, host/path routing, authentication integration, and HTTP-to-HTTPS redirects. Nginx Proxy Manager (NPM) was decommissioned and deleted after the migration; it is not a viable rollback target.
Internet / internal clients
|
DNS + firewall
|
traefik-1 (192.168.10.110)
|
Traefik v3 + middleware
| | |
Keycloak Internal Public-facing
OAuth services applications
| Property | Value |
|---|---|
| Host | traefik-1.barnesbears.xyz |
| IP | 192.168.10.110 |
| OS | Ubuntu Server 24.04 LTS |
| Application | Traefik v3, Docker |
| Management | Portainer and Traefik Manager |
| Authentication | Keycloak (BarnesBears realm), oauth2-proxy |
| Monitoring | Zabbix Agent 2, Traefik metrics |
| Public ports | TCP 80 and 443, forwarded to Traefik |
| Internal DNS | BarnesBears AD DNS; service hostnames resolve to proxy address |
Configuration layout
The original standardized layout uses /opt/traefik/:
/opt/traefik/
├── config/
│ ├── traefik.yml
│ └── dynamic/
│ ├── routes.yml
│ └── tls.yml
├── data/
│ └── acme.json
├── logs/
│ ├── access.log
│ └── traefik.log
└── manager/
├── config/
└── backups/
Paths above reflect the documented layout; check actual container mounts and current file locations before editing:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
docker inspect traefik --format '{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}'
The Traefik stack and related containers are administered with Portainer. Preserve persistent volumes, configuration and plugin storage across recreations.
Routing and naming conventions
Use predictable names:
- Router:
<service>-router - Backend service:
<service>-service - DNS names: service aliases such as
files.barnesbears.xyz,photos.barnesbears.xyz,recipes.barnesbears.xyzandbird.barnesbears.xyzrefer to services, not physical hosts.
The barnesbears.xyz namespace is used for infrastructure and service hostnames. davidplace.net also hosts externally routed applications and paths.
Examples of proxied applications include Nextcloud, Immich, WordPress, Home Assistant, Frigate, Sonarr, Radarr, NZBGet, MeTube, Kodi, Calibre, Requestrr, Heimdall, Zabbix, and other home-lab services. Verify the current router inventory in Traefik Manager rather than treating this list as an exact export.
Authentication and middleware
Keycloak is the identity provider (realm: BarnesBears); oauth2-proxy integrates it with Traefik ForwardAuth. The July 2026 standard middleware chain was:
- OAuth error handler
- OAuth ForwardAuth
- Compression
Apply authentication middleware only where appropriate. Applications with their own authentication or integrations requiring unauthenticated callbacks may need exceptions; Requestrr uses Discord authentication.
OAuth cookie domains include .barnesbears.xyz and .davidplace.net. Check redirect URIs and cookie configuration when diagnosing login loops. Do not commit client secrets, cookie secrets, or credentials to this repository.
TLS and certificates
Let's Encrypt certificates are managed by Traefik and persisted in acme.json. A router generally needs TLS enabled and the configured certificate resolver selected. The self-signed/default certificate and NPM forwarding steps described in early migration notes are historical, not the production standard.
Useful checks:
docker logs --tail 100 traefik
curl -s http://127.0.0.1:8082/metrics | grep 'traefik_tls_certs_not_after'
The metrics command uses the endpoint verified on traefik-1 in October 2026. Zabbix monitors certificate expiry; stale metrics entries were observed clearing after restarting the Traefik container. Investigate the underlying certificate and router before restarting services.
Immich has historically needed generous Traefik read/idle timeouts (600 seconds) for long operations; no buffering middleware was required in the original migration.
CrowdSec integration
CrowdSec provides detection and enforcement through Traefik middleware/bouncer integration. A previous incident occurred when recreating the CrowdSec container removed plugin storage, leaving an invalid bouncer middleware. Persistent /plugins-storage was the remediation.
October 2026 investigation also found false-positive probing detection for Immich-backed WordPress thumbnail URLs using /wp-admin/admin-ajax.php. A narrowly scoped local parser was introduced and validated with cscli explain; do not globally disable probing protections.
Operational checks:
docker exec crowdsec crowdsec -t
docker exec crowdsec cscli decisions list
docker exec crowdsec cscli alerts list
Only restart CrowdSec after validating its configuration. For the detailed false-positive procedure, refer to the separate CrowdSec incident documentation maintained in the home-lab knowledge base.
Home Assistant read-only route (ha-ro)
Home Assistant is not normally reached through Traefik: internal clients use homeassistant.barnesbears.xyz / ha.barnesbears.xyz, which resolve directly to 192.168.10.18. Traefik carries one deliberately restricted HA route, ha-ro, which gives Wadsworth (the OpenClaw agent) read-only access to Home Assistant state. Added October 2026.
Home Assistant long-lived tokens cannot be made read-only, so the restriction is enforced in Traefik, and the token never leaves Traefik:
| Component | Setting |
|---|---|
| Hostname | ha-ro.barnesbears.xyz → 192.168.10.110 (internal DNS only, not public) |
| Router | ha-ro-router, entry point websecure, Let's Encrypt resolver, no OAuth chain |
| Rule | GET only, to /api/states, /api/states/* and /api/config (full rule below) |
| Middleware 1 | ha-ro-allowlist: ipAllowList permitting only 192.168.10.172/32 (OpenClaw host) |
| Middleware 2 | ha-ro-token: headers.customRequestHeaders setting Authorization: Bearer <token>, written in the Traefik Manager raw YAML editor (the Secure/CORS header wizards cannot set request headers) |
| Service | homeassistant-service → http://192.168.10.18:8123 |
| HA identity | Dedicated non-admin HA user wadsworth and its long-lived token |
Router rule (entered with Traefik Manager's Advanced rule editor, v1.14.1 or later):
Host(`ha-ro.barnesbears.xyz`) && Method(`GET`) && (Path(`/api/states`) || PathPrefix(`/api/states/`) || Path(`/api/config`))
Home Assistant must trust Traefik as a proxy (configuration.yaml):
http:
use_x_forwarded_for: true
trusted_proxies:
- 192.168.10.110
Expected behaviour, verified 20 October 2026 from the OpenClaw host:
GET /api/states,GET /api/states/<entity_id>andGET /api/config→200.- Any other path (
/api/,/api/services,/api/events,/api/error_log) or any other method →404from Traefik; the request never reaches Home Assistant. - Requests from any other source address should get
403from the allowlist. This can only be tested from a host other than192.168.10.172and had not yet been verified at the time of writing.
Never loosen the rule
The router injects a valid HA token. If its rule is reduced to Host(...) alone, the route forwards anything, including POST service calls, with that token attached. Keep the method and path restrictions in place.
Revoking access: delete the wadsworth user's token in Home Assistant (Profile → Security), or remove ha-ro-router and its middlewares. The token value lives only in the Traefik dynamic configuration; do not copy it into this repository or into Git-backed Traefik Manager backups.
Monitoring and recovery
Zabbix Agent 2 monitors Traefik, including reloads, open file descriptors, goroutines, and certificate expiration. A guarded recovery script was deployed at /usr/local/sbin/zabbix-recover-traefik with restricted sudo permissions.
Useful checks:
docker ps --filter name=traefik
docker logs --tail 100 traefik
curl -I http://192.168.10.110/
The Traefik API can expose /api/overview, /api/http/routers, /api/http/services, and /api/http/middlewares, depending on API configuration and access controls. Keep the dashboard/API protected.
Backup and disaster recovery
Back up:
- Portainer stack definitions and Compose configuration
- Static and dynamic Traefik configuration
- Traefik Manager configuration and backups
acme.json(sensitive; preserve permissions and protect backup)- OAuth configuration and securely stored secrets
- CrowdSec configuration, local parsers and persistent plugin storage
No NPM fallback
Nginx Proxy Manager has been removed. Do not follow historical instructions to start npm-1 or switch NAT back to it. Recovery now means restoring Traefik's configuration and persistent data, or rebuilding Traefik from documented backups.
Troubleshooting quick reference
| Symptom | Check |
|---|---|
| Certificate not issued | DNS, port 80/443 forwarding, router TLS, resolver, ACME logs |
| Traefik 404 | Host/Path rule, entrypoint, middleware, backend route |
| 502 / 504 | Backend reachability, IP, port, application status, timeout |
| OAuth loop | oauth2-proxy, Keycloak, cookies, callback URL, middleware |
| Bouncer middleware error | CrowdSec health, plugin persistence, Traefik logs |
| Zabbix certificate warning | Actual certificate expiry vs stale Traefik metrics |
See Traefik Standards & Migration for the detailed onboarding procedure and migration record.