Traefik
Reverse proxy configuration, routers, wildcard routing, and host/container boundary.
Traefik
Traefik is the ByteBite edge reverse proxy. On staging it runs as the dokploy-traefik container managed by Dokploy, not as a Docker Swarm service.
Verified: 2026-09-08
Container
| Attribute | Value |
|---|---|
| Container name | dokploy-traefik |
| Image | traefik:v3.6.7 |
| Restart policy | always |
| Network | dokploy-network |
| Command | /entrypoint.sh traefik |
Public bindings
| Port | Protocol |
|---|---|
| 80 | TCP |
| 443 | TCP |
| 443 | UDP (HTTP/3) |
Mounts
| Host path | Container path | Mode |
|---|---|---|
/etc/dokploy/traefik/traefik.yml | /etc/traefik/traefik.yml | — |
/etc/dokploy/traefik/dynamic | /etc/dokploy/traefik/dynamic | — |
/var/run/docker.sock | /var/run/docker.sock | read-only |
/etc/dokploy/traefik/secrets | /run/secrets | read-only |
The secrets mount supports DNS-01 wildcard TLS. Environment variable:
CF_DNS_API_TOKEN_FILE=/run/secrets/cloudflare-dns-api-tokenThe token file on the host is /etc/dokploy/traefik/secrets/cloudflare-dns-api-token (mode 600, owner root:root). Never document the token value.
Static configuration (traefik.yml)
Observed providers:
| Provider | Settings |
|---|---|
| swarm | enabled |
| docker | exposedByDefault: false, watch: true, network: dokploy-network |
| file | directory: /etc/dokploy/traefik/dynamic, watch: true |
Entry points:
| Name | Port |
|---|---|
web | 80 |
websecure | 443 |
HTTP/3 advertised port: 443.
websecure default TLS resolver: letsencrypt.
Traefik API: insecure: true (static config fact). External accessibility of the API is not established — do not assume it is reachable from the internet.
Dynamic directory
Host path: /etc/dokploy/traefik/dynamic/
| File / directory | Purpose |
|---|---|
acme.json | HTTP-01 ACME state (explicit hosts) |
acme-cloudflare.json | DNS-01 ACME state (wildcard) |
dokploy.yml | Dokploy management-domain router |
middlewares.yml | redirect-to-https middleware |
certificates/ | Additional certificate material |
A temporary wildcard certificate probe router was removed after successful wildcard rollout. It is not a permanent architecture component.
TLS resolvers
| Resolver | Challenge | Storage | Used for |
|---|---|---|---|
letsencrypt | HTTP-01 (web entrypoint) | acme.json | Explicit Dokploy UI domains |
letsencrypt-cloudflare | DNS-01 (Cloudflare) | acme-cloudflare.json | *.staging.getbytebite.co wildcard |
ACME email (both resolvers): info@berkearas.de
See TLS for certificate details.
Explicit routers (Dokploy-injected)
Dokploy injects Host() routers for domains configured in the UI. These use the letsencrypt HTTP-01 resolver and take precedence over wildcard routers.
Verified explicit hosts (2026-09-08): all return valid Let's Encrypt TLS with HTTP → HTTPS redirect.
Wildcard routers (compose.deploy.yml)
Dokploy cannot configure *.staging.getbytebite.co in the domain UI. Wildcard routing is defined via Docker labels on storefront and api.
Hostname rule
Runtime rule:
HostRegexp(`^[a-z0-9-]+[.]staging[.]getbytebite[.]co$`)In compose.deploy.yml, the final $ is escaped as $$ because Docker Compose treats $ as variable interpolation. At runtime Traefik receives a single $.
Router inventory
| Logical name | Entrypoint | Priority | Middleware | Target port | TLS resolver |
|---|---|---|---|---|---|
bytebite-staging-wildcard-web | web | 10 | redirect-to-https@file | storefront 3000 | — |
bytebite-staging-wildcard-storefront | websecure | 10 | bytebite-staging-auth | storefront 3000 | letsencrypt-cloudflare |
bytebite-staging-wildcard-api | websecure | 20 | bytebite-staging-auth, bytebite-staging-wildcard-strip-api | api 3001 | letsencrypt-cloudflare |
bytebite-staging-storefront | websecure | 100 | bytebite-staging-auth | storefront 3000 | letsencrypt |
bytebite-staging-api | websecure | 100 | bytebite-staging-auth | api 3001 | letsencrypt |
bytebite-staging-dashboard | websecure | 100 | bytebite-staging-auth | dashboard 8080 | letsencrypt |
bytebite-staging-docs | websecure | 100 | bytebite-staging-auth | docs 3002 | letsencrypt |
bytebite-staging-reserved-api | websecure | 200 | bytebite-staging-auth, bytebite-staging-wildcard-strip-api | api 3001 | letsencrypt |
There is no separate wildcard HTTP API router. The wildcard HTTP router redirects /api/* to HTTPS; the HTTPS API router handles API traffic.
HTTP routers do not apply BasicAuth — they only redirect to HTTPS, where the prompt happens.
Staging BasicAuth
Middleware bytebite-staging-auth is defined on the api service labels (users from STAGING_BASIC_AUTH_USERS, realm ByteBite Staging, removeHeader=true). Storefront, dashboard, and docs routers reference the same Docker-provider middleware.
dokploy.getbytebite.co is a Dokploy platform router and is not in this inventory.
Generate the users string with infrastructure/scripts/staging-htpasswd.sh. SHA hashes are preferred in Dokploy because they contain no $ for Compose interpolation. After changing the variable, redeploy so labels are rewritten.
See Security for the enable procedure.
Priority and precedence
Wildcard priorities stay low (10 storefront, 20 API) so they remain a catch-all for tenant slugs.
Explicit BasicAuth routers in compose.deploy.yml use priority 100 (hosts) and 200 (same-origin /api) so they win over Dokploy UI Host() routers, whose default priority is approximately the rule length. That is required: otherwise the unauthenticated Dokploy routers would keep serving reserved hosts.
The wildcard still matches one-label staging hosts including reserved names; the higher-priority explicit routers send those names to the correct service and require BasicAuth.
TLS domain on wildcard routers
tls.domains[0].main = *.staging.getbytebite.co
certResolver = letsencrypt-cloudflareLocal Traefik (development)
Local dev uses a separate Traefik container (traefik:v3.4 in compose.yml) with the file provider only. Docker provider is disabled for OrbStack compatibility. Routing is defined in infrastructure/traefik/dev/dynamic.yml.
Host vs container configuration boundary
| Configuration | Location | Survives app deploy? | Survives Dokploy Traefik recreate? |
|---|---|---|---|
| Wildcard Traefik labels | compose.deploy.yml (Git) | Yes (on redeploy) | Yes |
| Staging BasicAuth users | Dokploy env → compose labels | Yes (on redeploy) | Yes |
| Explicit domain labels | Dokploy UI / Preview Compose | Yes | Yes |
traefik.yml static config | Host filesystem | Yes | May be lost if container recreated without remount |
acme-cloudflare.json | Host filesystem | Yes | Yes (file persists) |
| Cloudflare token file | Host filesystem | Yes | May be lost if secret mount not restored |
CF_DNS_API_TOKEN_FILE env | Container config | — | May be lost on recreate |
This is a critical operations concern. See Operations.
Related
- TLS — certificate issuance and renewal
- Network —
dokploy-network - Dokploy — domain UI vs repository labels
- Troubleshooting — routing failures
- Security — staging BasicAuth