This page documents the actual Traefik setup used in Enclari and provides copy‑paste snippets that match the running Compose files.
traefik:v2.11/opt/stack/traefik/dynamic)web (80) with redirect to websecure (443), websecure (443)web (external)https://traefik.enclari.com protected behind Authentik ForwardAuth--providers.docker=true
--providers.docker.exposedbydefault=false
--providers.docker.network=web
--providers.file.directory=/dynamic
--providers.file.watch=true
--entrypoints.web.address=:80
--entrypoints.web.http.redirections.entrypoint.to=websecure
--entrypoints.web.http.redirections.entrypoint.scheme=https
--entrypoints.websecure.address=:443
--certificatesresolvers.le.acme.email=$LETSENCRYPT_EMAIL
--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
--certificatesresolvers.le.acme.dnschallenge=true
--certificatesresolvers.le.acme.dnschallenge.provider=hetzner
--api.dashboard=true
--api.insecure=false
--log.level=INFO
Security headers used across routers:
# labels on traefik service
- traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000
- traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true
- traefik.http.middlewares.secure-headers.headers.stsPreload=true
- traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true
- traefik.http.middlewares.secure-headers.headers.browserXssFilter=true
- traefik.http.middlewares.secure-headers.headers.referrerPolicy=no-referrer
- traefik.http.middlewares.secure-headers.headers.frameDeny=true
The ForwardAuth middleware for Authentik is defined by the file provider in /opt/stack/traefik/dynamic/authentik.yml and referenced from routers as authentik-forwardauth@file:
# /opt/stack/traefik/dynamic/authentik.yml (excerpt)
http:
middlewares:
authentik-forwardauth:
forwardAuth:
address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
authRequestHeaders: [X-Forwarded-Method, X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Uri, X-Forwarded-Port, X-Real-IP, Authorization, Cookie]
authResponseHeaders: [..., Set-Cookie, X-Authentik-Username, X-Authentik-Groups, X-Authentik-Email]
Duplicates (checked 2026-09-30): the same name is also defined in
dynamic/forwardauth.yml(public addresshttps://auth.enclari.com/...) and as labels on thetraefikcontainer (@docker). Traefik reads the directory alphabetically and skips a repeated name, soauthentik.ymlwins; the other two are unused. Cleanup is listed in /ops/security.
# labels on the traefik service
- traefik.http.routers.traefik.rule=Host(`traefik.enclari.com`)
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.tls=true
- traefik.http.routers.traefik.tls.certresolver=le
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.middlewares=authentik-forwardauth@file,secure-headers@docker
Use this pattern on any app container (e.g., Portainer, Dashy, Netdata, phpMyAdmin). Note the reuse of authentik-forwardauth@file and the security headers.
# labels on the target app service, example: Portainer
- traefik.enable=true
- traefik.docker.network=web
- traefik.http.routers.portainer.rule=Host(`portainer.enclari.com`)
- traefik.http.routers.portainer.entrypoints=websecure
- traefik.http.routers.portainer.tls=true
- traefik.http.routers.portainer.tls.certresolver=le
- traefik.http.routers.portainer.middlewares=authentik-forwardauth@file,secure-headers@docker
# adjust the internal port to your app
- traefik.http.services.portainer.loadbalancer.server.port=9000
Authentik Traefik outpost endpoints live under /outpost.goauthentik.io/. Requests to that path on each protected host must be forwarded to the Authentik server. You already define these on the authentik server service for every host. Here is the pattern (one example shown; you have similar labels for Dashy, Portainer, Netdata, phpMyAdmin and the Traefik host):
# labels on authentik server service
- traefik.http.routers.ak-portainer.rule=Host(`portainer.enclari.com`) && PathPrefix(`/outpost.goauthentik.io/`)
- traefik.http.routers.ak-portainer.entrypoints=websecure
- traefik.http.routers.ak-portainer.tls=true
- traefik.http.routers.ak-portainer.tls.certresolver=le
- traefik.http.routers.ak-portainer.service=authentik
- traefik.http.routers.ak-portainer.priority=1000
# service authentik points to the authentik-server on port 9000 (defined on the same service):
- traefik.http.routers.authentik.rule=Host(`${AUTHENTIK_DOMAIN}`)
- traefik.http.routers.authentik.entrypoints=websecure
- traefik.http.routers.authentik.tls=true
- traefik.http.routers.authentik.tls.certresolver=le
- traefik.http.routers.authentik.service=authentik
- traefik.http.services.authentik.loadbalancer.server.port=9000
- traefik.http.services.authentik.loadbalancer.server.scheme=http
# labels on traefik service
- traefik.http.routers.www-redirect.rule=Host(`www.enclari.com`)
- traefik.http.routers.www-redirect.entrypoints=websecure
- traefik.http.routers.www-redirect.tls=true
- traefik.http.routers.www-redirect.tls.certresolver=le
- traefik.http.routers.www-redirect.middlewares=redir-www-to-apex@docker
- traefik.http.middlewares.redir-www-to-apex.redirectregex.regex=^https://www\.enclari\.com/(.*)
- traefik.http.middlewares.redir-www-to-apex.redirectregex.replacement=https://enclari.com/$$1
- traefik.http.middlewares.redir-www-to-apex.redirectregex.permanent=true
authentik-forwardauth@file (defined in /opt/stack/traefik/dynamic/authentik.yml).web to make the private DNS names and headers work.secure-headers middleware on public and admin routes.web network, never use a generic DB hostname like db: authentik-db-1 owns that alias there. Use a unique service or container name (e.g. eventkit-db, docs-db)./opt/stack/traefik/letsencrypt/acme.json (mounted to /letsencrypt in the container). Make sure it is backed up.