Traefik Labels Reference¶
Complete reference for all Traefik Docker labels used in container configuration.
Quick Reference¶
| Label | Purpose | Example |
|---|---|---|
traefik.enable | Enable Traefik for container | true |
traefik.http.routers.[name].rule | Route matching rule | Host(\app.com`)` |
traefik.http.routers.[name].entrypoints | Which ports/protocols | websecure |
traefik.http.routers.[name].tls.certresolver | SSL certificate resolver | letsencrypt |
traefik.http.services.[name].loadbalancer.server.port | Container port | 8000 |
traefik.http.middlewares.[name].[type] | Request/response modifiers | Various |
traefik.http.routers.[name].middlewares | Apply middlewares | my-auth,compress |
Enable/Disable¶
traefik.enable¶
Enable or disable Traefik routing for this container.
# ✅ Enable Traefik for this container
- traefik.enable=true
# ❌ Disable (container ignored by Traefik)
- traefik.enable=false
Default: false (disabled)
When to use: Always set to true for services you want to expose to the internet.
Routers¶
Routers define which requests match this service.
Router Definition¶
Label format: traefik.http.routers.[router-name].[property]
The [router-name] must be: - Unique per container - Lowercase, alphanumeric, hyphens allowed - Should be descriptive (e.g., my-app, api-service)
traefik.http.routers.[name].rule¶
The rule that determines when traffic routes to this service.
Host-based routing - Match specific domains:
# Single domain
- traefik.http.routers.my-app.rule=Host(`app.egygeeks.com`)
# Multiple domains (OR logic)
- traefik.http.routers.my-app.rule=Host(`app.egygeeks.com`) || Host(`example.com`)
# Subdomain wildcard
- traefik.http.routers.my-app.rule=HostRegexp(`^.*\.egygeeks\.com$`)
Path-based routing - Match URL paths:
# Exact path
- traefik.http.routers.api.rule=Path(`/api`)
# Path prefix (matches /api, /api/users, /api/posts, etc.)
- traefik.http.routers.api.rule=PathPrefix(`/api`)
# Path with regex
- traefik.http.routers.api.rule=PathRegexp(`^/api/v[0-9]+/.*$`)
Method-based routing - Match HTTP methods:
# Only GET requests
- traefik.http.routers.api.rule=PathPrefix(`/api`) && Method(`GET`)
# POST or PUT
- traefik.http.routers.api.rule=PathPrefix(`/api`) && Method(`POST`, `PUT`)
Combined rules - Mix and match:
# Host AND PathPrefix (both must match)
- traefik.http.routers.api.rule=Host(`api.egygeeks.com`) && PathPrefix(`/v1`)
# Host OR PathPrefix (either can match)
- traefik.http.routers.api.rule=Host(`api.egygeeks.com`) || PathPrefix(`/api`)
# Complex: Host AND (Method OR PathPrefix)
- traefik.http.routers.api.rule=Host(`api.egygeeks.com`) && (Method(`GET`) || PathPrefix(`/search`))
Rule functions reference:
| Function | Example | Matches |
|---|---|---|
Host() | Host(\app.com`)` | Domain name |
HostRegexp() | HostRegexp(\^.*.com$`)` | Domain regex pattern |
Path() | Path(\/api`)` | Exact URL path |
PathPrefix() | PathPrefix(\/api`)` | URL path prefix |
PathRegexp() | PathRegexp(\^/api/.*`)` | URL path regex |
Method() | Method(\GET`, `POST`)` | HTTP method |
Header() | Header(\X-Custom`, `value`)` | HTTP header |
HeaderRegexp() | HeaderRegexp(\X-Api`, `v[0-9]+`)` | Header regex |
Query() | Query(\action`, `login`)` | Query parameter |
QueryRegexp() | QueryRegexp(\id`, `[0-9]+`)` | Query param regex |
traefik.http.routers.[name].entrypoints¶
Which entry point(s) this router listens on.
# HTTPS only
- traefik.http.routers.my-app.entrypoints=websecure
# HTTP only
- traefik.http.routers.my-app.entrypoints=web
# Both HTTP and HTTPS
- traefik.http.routers.my-app.entrypoints=web,websecure
Available entrypoints:
| Entrypoint | Port | Protocol |
|---|---|---|
web | 80 | HTTP |
websecure | 443 | HTTPS |
Common patterns:
# Modern production (HTTPS only)
- traefik.http.routers.app.entrypoints=websecure
# Development (HTTP)
- traefik.http.routers.app.entrypoints=web
# Accept both
- traefik.http.routers.app.entrypoints=web,websecure
traefik.http.routers.[name].tls¶
Configure TLS/HTTPS for this router.
traefik.http.routers.[name].tls.certresolver¶
Which certificate resolver to use for HTTPS.
# Use Let's Encrypt for automatic certificates
- traefik.http.routers.my-app.tls.certresolver=letsencrypt
# No TLS (HTTP only)
- traefik.http.routers.my-app.entrypoints=web
# (no tls.certresolver needed)
Certificate resolvers available:
letsencrypt- Automatic Let's Encrypt certificates (recommended)
When to use:
- Set this if using
websecureentrypoint - Leave empty if using only
webentrypoint
Full HTTPS example:
labels:
- traefik.enable=true
- traefik.http.routers.my-app.rule=Host(`app.egygeeks.com`)
- traefik.http.routers.my-app.entrypoints=websecure
- traefik.http.routers.my-app.tls.certresolver=letsencrypt
Services¶
Services define where traffic is actually sent.
Service Definition¶
Label format: traefik.http.services.[service-name].[property]
Usually [service-name] matches the router name.
traefik.http.services.[name].loadbalancer.server.port¶
The port inside the container that Traefik forwards traffic to.
# Node.js/Express on port 3000
- traefik.http.services.my-app.loadbalancer.server.port=3000
# Python Flask on port 5000
- traefik.http.services.my-app.loadbalancer.server.port=5000
# Static site on port 8000
- traefik.http.services.my-app.loadbalancer.server.port=8000
Important: This is the port inside the container, not on the host machine.
Port mapping reference:
| Technology | Port |
|---|---|
| Node.js/Express | 3000 |
| Python/Flask | 5000 |
| Python/FastAPI | 8000 |
| Go applications | 8080 |
| Ruby on Rails | 3000 |
| Django | 8000 |
| Static HTTP | 8000 |
| PostgreSQL | 5432 |
| MySQL | 3306 |
traefik.http.services.[name].loadbalancer.server.scheme¶
The protocol used to communicate with the backend.
# Standard HTTP (default)
- traefik.http.services.my-app.loadbalancer.server.scheme=http
# For backends that require HTTPS
- traefik.http.services.my-app.loadbalancer.server.scheme=https
Default: http
When to use: Leave as default unless your container specifically requires HTTPS communication.
traefik.http.services.[name].loadbalancer.healthcheck.path¶
Health check path for the service.
# Check root path
- traefik.http.services.my-app.loadbalancer.healthcheck.path=/
# Check health endpoint
- traefik.http.services.my-app.loadbalancer.healthcheck.path=/health
# Check API status
- traefik.http.services.my-app.loadbalancer.healthcheck.path=/api/status
Note: Traefik primarily uses Docker health checks. This is an additional configuration.
Middlewares¶
Middlewares modify requests before they reach your app, or modify responses before returning to users.
Middleware Definition¶
Label format: traefik.http.middlewares.[middleware-name].[middleware-type]
traefik.http.routers.[name].middlewares¶
Apply middlewares to a router.
# Single middleware
- traefik.http.routers.my-app.middlewares=my-auth
# Multiple middlewares (applied in order)
- traefik.http.routers.my-app.middlewares=compress,my-auth,ratelimit
Processing order matters: Middlewares execute left-to-right.
Strip Prefix Middleware¶
Remove a path prefix before forwarding to the container.
Use case: Container serves from /, but you access it at /api
labels:
# Define the middleware
- traefik.http.middlewares.api-strip.stripprefix.prefixes=/api
# Define the router
- traefik.http.routers.api.rule=PathPrefix(`/api`)
- traefik.http.routers.api.middlewares=api-strip
# Define the service
- traefik.http.services.api.loadbalancer.server.port=3000
How it works:
Multiple prefixes:
Basic Auth Middleware¶
Require username and password.
Create credentials file on server:
# Generate htpasswd credentials
htpasswd -c /opt/traefik/.htpasswd username
# Add more users
htpasswd /opt/traefik/.htpasswd another-user
Mount in Traefik container:
Apply to service:
labels:
- traefik.http.middlewares.my-auth.basicauth.usersfile=/etc/traefik/.htpasswd
- traefik.http.routers.my-app.middlewares=my-auth
Compress Middleware¶
Enable gzip compression.
labels:
- traefik.http.middlewares.compress.compress=true
- traefik.http.routers.my-app.middlewares=compress
Benefits:
- Reduces response size by 60-80%
- Slower for tiny responses (<1KB)
- Automatic decompression in browsers
Rate Limit Middleware¶
Limit requests per time period.
labels:
# 100 requests per minute
- traefik.http.middlewares.ratelimit.ratelimit.average=100
- traefik.http.middlewares.ratelimit.ratelimit.period=1m
- traefik.http.routers.api.middlewares=ratelimit
Parameters:
average- Number of requests allowedperiod- Time window (e.g.,1m,1s,1h)burst- (optional) Temporary spike allowance
Redirect Middleware¶
Redirect HTTP to HTTPS or other URLs.
HTTP to HTTPS:
labels:
# Redirect www to non-www
- traefik.http.middlewares.redirect.redirectregex.regex=^http://www\.(.*)
- traefik.http.middlewares.redirect.redirectregex.replacement=https://$${1}
- traefik.http.middlewares.redirect.redirectregex.permanent=true
- traefik.http.routers.my-app.middlewares=redirect
Headers Middleware¶
Add or modify HTTP headers.
labels:
# Add security headers
- traefik.http.middlewares.headers.headers.customresponseheaders.X-Content-Type-Options=nosniff
- traefik.http.middlewares.headers.headers.customresponseheaders.X-Frame-Options=SAMEORIGIN
- traefik.http.middlewares.headers.headers.customresponseheaders.Strict-Transport-Security=max-age=31536000
- traefik.http.routers.my-app.middlewares=headers
CORS Middleware¶
Enable Cross-Origin Resource Sharing.
labels:
- traefik.http.middlewares.cors.headers.accesscontrolalloworiginlist=https://example.com,https://another.com
- traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,POST,PUT,DELETE
- traefik.http.middlewares.cors.headers.accesscontrolmaxage=100
- traefik.http.routers.api.middlewares=cors
Complete Examples¶
Single Application¶
services:
my-app:
image: my-app:latest
container_name: my-app
restart: unless-stopped
labels:
- traefik.enable=true
# Route: Domain-based
- traefik.http.routers.my-app.rule=Host(`app.egygeeks.com`)
- traefik.http.routers.my-app.entrypoints=websecure
- traefik.http.routers.my-app.tls.certresolver=letsencrypt
# Service: Container port
- traefik.http.services.my-app.loadbalancer.server.port=3000
networks:
- traefik_public
networks:
traefik_public:
external: true
Multiple Services with Path Prefix¶
services:
docs:
image: docs:latest
labels:
- traefik.enable=true
- traefik.http.routers.docs.rule=PathPrefix(`/docs`)
- traefik.http.middlewares.docs-strip.stripprefix.prefixes=/docs
- traefik.http.routers.docs.middlewares=docs-strip
- traefik.http.services.docs.loadbalancer.server.port=8000
networks:
- traefik_public
api:
image: api:latest
labels:
- traefik.enable=true
- traefik.http.routers.api.rule=PathPrefix(`/api`)
- traefik.http.middlewares.api-strip.stripprefix.prefixes=/api
- traefik.http.routers.api.middlewares=api-strip
- traefik.http.services.api.loadbalancer.server.port=3000
networks:
- traefik_public
networks:
traefik_public:
external: true
With Authentication¶
labels:
- traefik.enable=true
# Define auth middleware
- traefik.http.middlewares.auth.basicauth.usersfile=/etc/traefik/.htpasswd
# Router
- traefik.http.routers.my-app.rule=Host(`app.egygeeks.com`)
- traefik.http.routers.my-app.entrypoints=websecure
- traefik.http.routers.my-app.tls.certresolver=letsencrypt
# Apply middleware
- traefik.http.routers.my-app.middlewares=auth
# Service
- traefik.http.services.my-app.loadbalancer.server.port=8000
With Multiple Middlewares¶
labels:
- traefik.enable=true
# Middlewares
- traefik.http.middlewares.strip.stripprefix.prefixes=/api
- traefik.http.middlewares.auth.basicauth.usersfile=/etc/traefik/.htpasswd
- traefik.http.middlewares.compress.compress=true
- traefik.http.middlewares.ratelimit.ratelimit.average=1000
- traefik.http.middlewares.ratelimit.ratelimit.period=1m
# Router
- traefik.http.routers.api.rule=PathPrefix(`/api`)
- traefik.http.routers.api.entrypoints=websecure
- traefik.http.routers.api.tls.certresolver=letsencrypt
# Apply all middlewares in order
- traefik.http.routers.api.middlewares=strip,auth,compress,ratelimit
# Service
- traefik.http.services.api.loadbalancer.server.port=3000
Load Balancing Multiple Instances¶
services:
app-1:
image: my-app:latest
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.egygeeks.com`)
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=letsencrypt
- traefik.http.services.app.loadbalancer.server.port=3000
networks:
- traefik_public
app-2:
image: my-app:latest
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.egygeeks.com`)
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=letsencrypt
- traefik.http.services.app.loadbalancer.server.port=3000
networks:
- traefik_public
networks:
traefik_public:
external: true
Both instances use the same router and service name. Traefik automatically balances traffic between them.
Label Naming Conventions¶
Router Names¶
Keep router names: - Unique - No duplicate names - Lowercase - my-app, not MyApp - Descriptive - api, docs, admin - Consistent - Match service and middleware names when related
Service Names¶
Usually match the router name:
# ✅ Good - names match
- traefik.http.routers.api.rule=...
- traefik.http.services.api.loadbalancer.server.port=3000
# ⚠️ Works, but confusing
- traefik.http.routers.api.rule=...
- traefik.http.services.backend.loadbalancer.server.port=3000
Middleware Names¶
Use descriptive names:
# ✅ Clear intent
- traefik.http.middlewares.api-auth.basicauth.usersfile=...
- traefik.http.middlewares.api-compress.compress=true
- traefik.http.middlewares.api-ratelimit.ratelimit.average=100
# ⚠️ Generic names less clear
- traefik.http.middlewares.m1.basicauth.usersfile=...
Common Mistakes¶
Mistake 1: Missing service.loadbalancer.server.port¶
# ❌ Incomplete - where does traffic go?
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.egygeeks.com`)
# ✅ Complete - specifies port
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.egygeeks.com`)
- traefik.http.services.app.loadbalancer.server.port=3000
Mistake 2: PathPrefix without StripPrefix¶
# ❌ Container expects requests at /
# but receives /api/users
labels:
- traefik.http.routers.api.rule=PathPrefix(`/api`)
- traefik.http.services.api.loadbalancer.server.port=3000
# ✅ Strip the /api prefix before sending to container
labels:
- traefik.http.routers.api.rule=PathPrefix(`/api`)
- traefik.http.middlewares.api-strip.stripprefix.prefixes=/api
- traefik.http.routers.api.middlewares=api-strip
- traefik.http.services.api.loadbalancer.server.port=3000
Mistake 3: Missing host constraint with path-based routing¶
# ⚠️ Works, but matches /api on ANY host
- traefik.http.routers.api.rule=PathPrefix(`/api`)
# ✅ Better - constrain to specific host
- traefik.http.routers.api.rule=Host(`50.3.85.110`) && PathPrefix(`/api`)
Mistake 4: TLS config on non-HTTPS entry point¶
# ❌ No sense - web is HTTP only
- traefik.http.routers.app.entrypoints=web
- traefik.http.routers.app.tls.certresolver=letsencrypt
# ✅ Correct - use websecure for HTTPS
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=letsencrypt
Mistake 5: Mismatched router and service names¶
# ⚠️ Router "app", service "backend" - confusing
labels:
- traefik.http.routers.app.rule=...
- traefik.http.services.backend.loadbalancer.server.port=3000
# ✅ Names match - easier to maintain
labels:
- traefik.http.routers.app.rule=...
- traefik.http.services.app.loadbalancer.server.port=3000
Related Documentation¶
- Overview - Architecture and concepts: overview.md
- Troubleshooting - Debug common issues: troubleshooting.md
- Templates - Ready-to-use configurations: Templates
For how-to guides on setting up Traefik, see the Journey guides.