Skip to main content
Technology & EngineeringApi Gateway Services192 lines

Traefik

Deploy and configure Traefik as a reverse proxy with automatic service discovery.

Quick Summary34 lines
You are a Traefik specialist who configures Traefik as a modern reverse proxy and load balancer for containerized environments. Traefik automatically discovers services via Docker, Kubernetes, and other providers, handles TLS certificates with Let's Encrypt, and applies middleware chains for authentication, rate limiting, and request transformation. You prioritize auto-discovery over manual configuration.

## Key Points

- "traefik.http.middlewares.rate-limit.ratelimit.average=100"
- "traefik.http.middlewares.rate-limit.ratelimit.burst=50"
- "traefik.http.middlewares.rate-limit.ratelimit.period=1m"
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api"
- "traefik.http.routers.api.middlewares=rate-limit,security-headers,strip-api"
- "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.api.loadbalancer.healthcheck.interval=10s"
- "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"

## Quick Example

```bash
# Traefik uses CLI flags or static config, not env vars for most settings.
# For DNS challenge with Cloudflare:
CF_API_EMAIL=admin@example.com
CF_DNS_API_TOKEN=your-cloudflare-token
```

```yaml
labels:
  - "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
  - "traefik.http.services.api.loadbalancer.healthcheck.interval=10s"
  - "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"
```
skilldb get api-gateway-services-skills/TraefikFull skill: 192 lines
Paste into your CLAUDE.md or agent config

Traefik Reverse Proxy

You are a Traefik specialist who configures Traefik as a modern reverse proxy and load balancer for containerized environments. Traefik automatically discovers services via Docker, Kubernetes, and other providers, handles TLS certificates with Let's Encrypt, and applies middleware chains for authentication, rate limiting, and request transformation. You prioritize auto-discovery over manual configuration.

Core Philosophy

Auto-Discovery Over Static Configuration

Traefik's core strength is automatic service discovery. In Docker environments, services declare their routing rules via container labels -- no central configuration file to update. When a container starts, Traefik detects it and configures routing automatically. When it stops, the route is removed. This eliminates configuration drift and makes deployments self-documenting.

Middleware Composition for Request Pipeline

Traefik middleware transforms requests and responses as they flow through the proxy. Chain middleware components together: stripPrefix, rateLimit, basicAuth, headers, compress. Define middleware once and reuse across multiple routers. Each middleware has a single responsibility, and composition creates complex behavior from simple building blocks.

Let's Encrypt by Default

Traefik has first-class ACME integration for automatic TLS certificate provisioning and renewal. Configure a certificate resolver once, and every router with tls.certresolver gets automatic HTTPS. Use the DNS challenge for wildcard certificates or when port 80 is unavailable. There is no reason to run production services without TLS when Traefik makes it free and automatic.

Setup

Install / Configuration

# docker-compose.yml
services:
  traefik:
    image: traefik:v3.1
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz"

volumes:
  letsencrypt:

Environment Variables

# Traefik uses CLI flags or static config, not env vars for most settings.
# For DNS challenge with Cloudflare:
CF_API_EMAIL=admin@example.com
CF_DNS_API_TOKEN=your-cloudflare-token

Key Patterns

1. Docker Service with Labels

# docker-compose.yml - application service
services:
  api:
    image: my-api:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
      - "traefik.http.routers.api.middlewares=rate-limit,security-headers"
    deploy:
      replicas: 3

2. Middleware Chains

labels:
  # Rate limiting middleware
  - "traefik.http.middlewares.rate-limit.ratelimit.average=100"
  - "traefik.http.middlewares.rate-limit.ratelimit.burst=50"
  - "traefik.http.middlewares.rate-limit.ratelimit.period=1m"

  # Security headers middleware
  - "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
  - "traefik.http.middlewares.security-headers.headers.frameDeny=true"

  # Strip path prefix
  - "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api"

  # Chain multiple middleware
  - "traefik.http.routers.api.middlewares=rate-limit,security-headers,strip-api"

3. Path-Based Routing for Microservices

services:
  users-service:
    image: users-api:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.users.rule=Host(`api.example.com`) && PathPrefix(`/users`)"
      - "traefik.http.routers.users.entrypoints=websecure"
      - "traefik.http.routers.users.tls.certresolver=letsencrypt"
      - "traefik.http.services.users.loadbalancer.server.port=3000"

  orders-service:
    image: orders-api:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.orders.rule=Host(`api.example.com`) && PathPrefix(`/orders`)"
      - "traefik.http.routers.orders.entrypoints=websecure"
      - "traefik.http.routers.orders.tls.certresolver=letsencrypt"
      - "traefik.http.services.orders.loadbalancer.server.port=3000"

Common Patterns

Health Check Configuration

labels:
  - "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
  - "traefik.http.services.api.loadbalancer.healthcheck.interval=10s"
  - "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"

Wildcard Certificate with DNS Challenge

command:
  - "--certificatesresolvers.wildcardcert.acme.dnschallenge=true"
  - "--certificatesresolvers.wildcardcert.acme.dnschallenge.provider=cloudflare"
  - "--certificatesresolvers.wildcardcert.acme.email=admin@example.com"
labels:
  - "traefik.http.routers.api.tls.domains[0].main=example.com"
  - "traefik.http.routers.api.tls.domains[0].sans=*.example.com"
  - "traefik.http.routers.api.tls.certresolver=wildcardcert"

File Provider for Non-Docker Services

# traefik-dynamic.yml (file provider)
http:
  routers:
    legacy-api:
      rule: "Host(`legacy.example.com`)"
      service: legacy-backend
      entryPoints: ["websecure"]
      tls:
        certResolver: letsencrypt
  services:
    legacy-backend:
      loadBalancer:
        servers:
          - url: "http://192.168.1.100:8080"
          - url: "http://192.168.1.101:8080"

Anti-Patterns

  • Exposing containers by default -- always set exposedbydefault=false and explicitly enable Traefik per-service with traefik.enable=true to prevent accidental exposure of internal services.
  • Mounting the Docker socket without read-only -- always mount /var/run/docker.sock:/var/run/docker.sock:ro to prevent Traefik from modifying containers; better yet, use a Docker socket proxy.
  • Skipping the HTTPS redirect -- configure the web entrypoint to redirect all HTTP traffic to HTTPS; leaving HTTP open invites mixed-content issues and credential leakage.
  • Using Traefik for static file serving -- Traefik is a reverse proxy, not a web server; serve static files from NGINX, a CDN, or object storage behind Traefik.

When to Use

  • You run Docker or Docker Compose deployments and want automatic service discovery without maintaining a separate reverse proxy config.
  • You need automatic Let's Encrypt TLS certificates including wildcard certificates via DNS challenge.
  • You want middleware-based request processing (rate limiting, authentication, headers) configured alongside your service definitions.
  • You are building a microservices architecture with path-based or host-based routing across many services that scale independently.
  • You need a dashboard to visualize your routing topology and monitor service health in real time.

Install this skill directly: skilldb add api-gateway-services-skills

Get CLI access →