Skip to content

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 websecure entrypoint
  • Leave empty if using only web entrypoint

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:

Request: GET /api/users
         ↓ (stripprefix middleware)
Container: GET /users

Multiple prefixes:

- traefik.http.middlewares.multi-strip.stripprefix.prefixes=/api,/v1,/v2

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:

traefik:
  volumes:
    - /opt/traefik/.htpasswd:/etc/traefik/.htpasswd:ro

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 allowed
  • period - 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


For how-to guides on setting up Traefik, see the Journey guides.