# Traefik — Cloud-Native Reverse Proxy with Service Discovery

> Practical guide to Traefik v3 — reverse proxy and load balancer with automatic service discovery, middlewares and TLS via Let's Encrypt for Docker.

Source: https://www.jpkc.com/db/en/cheatsheets/web-servers/traefik/

<!-- PROSE:intro -->
Traefik is a modern, cloud-native reverse proxy and load balancer that wires up your services for you. Its signature trick is automatic service discovery: through providers for Docker, Kubernetes or file-based configuration, Traefik continuously reads which containers and backends exist and builds its routers and services at runtime – with no reload. TLS is just as effortless: with a certificate resolver, Traefik fetches and renews Let's Encrypt certificates on its own. This guide takes you from the static base configuration through Docker labels and middlewares to the router rules that let you steer traffic with precision.
<!-- PROSE:intro:end -->

## CLI & Static Configuration

`traefik --configFile=<path>` — Start Traefik with a specific configuration file.

```bash
traefik --configFile=/etc/traefik/traefik.yml
```

`traefik version` — Show the Traefik version.

```bash
traefik version
```

`traefik healthcheck` — Run a health check against a running Traefik instance.

```bash
traefik healthcheck --ping
```

`entryPoints:` — Define entry points for HTTP and HTTPS traffic (traefik.yml).

```yaml
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"
```

`api:` — Enable the Traefik dashboard. `insecure: true` exposes it unprotected and belongs in development only – in production, secure the dashboard behind a router and middleware.

```yaml
api:
  dashboard: true
  insecure: true  # Access at http://localhost:8080
```

`providers.docker:` — Enable the Docker provider for auto-discovery of containers. The mounted Docker socket grants root-equivalent access – mount it read-only (`:ro`) and restrict access tightly.

```yaml
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
```

`providers.file:` — Enable file-based dynamic configuration with auto-reload.

```yaml
providers:
  file:
    directory: /etc/traefik/dynamic/
    watch: true
```

## Docker Labels — Routing

`traefik.enable=true` — Enable Traefik for this container (when `exposedByDefault` is false).

```yaml
labels:
  - traefik.enable=true
```

`` traefik.http.routers.<name>.rule=Host(`<domain>`) `` — Route traffic based on the hostname.

```yaml
labels:
  - traefik.http.routers.myapp.rule=Host(`app.example.com`)
```

`` traefik.http.routers.<name>.rule=Host(`<domain>`) && PathPrefix(`<path>`) `` — Route based on hostname and URL path prefix.

```yaml
labels:
  - traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)
```

`traefik.http.routers.<name>.entrypoints=<entry>` — Specify which entry points the router should listen on.

```yaml
labels:
  - traefik.http.routers.myapp.entrypoints=websecure
```

`traefik.http.services.<name>.loadbalancer.server.port=<port>` — Set the port of the backend service inside the container.

```yaml
labels:
  - traefik.http.services.myapp.loadbalancer.server.port=8080
```

`traefik.http.routers.<name>.priority=<n>` — Set the router priority (higher number = higher priority).

```yaml
labels:
  - traefik.http.routers.specific.priority=100
```

## Docker Labels — TLS & Let's Encrypt

`traefik.http.routers.<name>.tls=true` — Enable TLS for a router.

```yaml
labels:
  - traefik.http.routers.myapp.tls=true
```

`traefik.http.routers.<name>.tls.certresolver=<resolver>` — Use a certificate resolver (Let's Encrypt) for automatic TLS.

```yaml
labels:
  - traefik.http.routers.myapp.tls.certresolver=letsencrypt
```

`certificatesResolvers (HTTP-01):` — Configure Let's Encrypt with the HTTP-01 challenge (traefik.yml).

```yaml
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      httpChallenge:
        entryPoint: web
```

`certificatesResolvers (DNS-01):` — Use the DNS-01 challenge for wildcard certificates.

```yaml
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
```

`traefik.http.routers.<name>.tls.domains[0].main=<domain>` — Set the main domain for the TLS certificate.

```yaml
labels:
  - traefik.http.routers.myapp.tls.domains[0].main=example.com
  - traefik.http.routers.myapp.tls.domains[0].sans=*.example.com
```

## Docker Labels — Middleware

`traefik.http.routers.<name>.middlewares=<middleware>` — Attach middleware to a router.

```yaml
labels:
  - traefik.http.routers.myapp.middlewares=redirect-https
```

`traefik.http.middlewares.<name>.redirectscheme.scheme=https` — Redirect HTTP to HTTPS.

```yaml
labels:
  - traefik.http.middlewares.redirect-https.redirectscheme.scheme=https
  - traefik.http.middlewares.redirect-https.redirectscheme.permanent=true
```

`traefik.http.middlewares.<name>.basicauth.users=<user:hash>` — Add HTTP Basic Authentication.

```yaml
labels:
  - traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$hash
```

`traefik.http.middlewares.<name>.headers.sslRedirect=true` — Force SSL redirect via headers middleware.

```yaml
labels:
  - traefik.http.middlewares.security.headers.sslRedirect=true
```

`traefik.http.middlewares.<name>.stripprefix.prefixes=<path>` — Strip a path prefix before forwarding to the backend.

```yaml
labels:
  - traefik.http.middlewares.strip-api.stripprefix.prefixes=/api
```

`traefik.http.middlewares.<name>.ratelimit.average=<n>` — Rate limiting: allow n requests per second on average.

```yaml
labels:
  - traefik.http.middlewares.ratelimit.ratelimit.average=100
  - traefik.http.middlewares.ratelimit.ratelimit.burst=50
```

`traefik.http.middlewares.<name>.compress=true` — Enable gzip compression for responses.

```yaml
labels:
  - traefik.http.middlewares.gzip.compress=true
```

`traefik.http.middlewares.<name>.ipallowlist.sourcerange=<cidr>` — Restrict access to specific IP ranges.

```yaml
labels:
  - traefik.http.middlewares.internal.ipallowlist.sourcerange=10.0.0.0/8,172.16.0.0/12
```

## Docker Compose — Full Example

`services: (Compose)` — Basic Traefik service in Docker Compose. The Docker socket is mounted read-only (`:ro`) – access to it is root-equivalent.

```yaml
services:
  traefik:
    image: traefik:v3.3
    command:
      - --providers.docker=true
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
```

`services: (App labels)` — Application service with Traefik labels for auto-discovery.

```yaml
services:
  app:
    image: myapp:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.app.rule=Host(`app.example.com`)
      - traefik.http.routers.app.tls.certresolver=letsencrypt
```

`networks:` — Use a shared external network so Traefik can reach services in other compose files.

```yaml
# Create first: docker network create traefik-net
networks:
  default:
    name: traefik-net
    external: true
```

## File-Based Dynamic Configuration

`http.routers:` — Define a router in a YAML dynamic configuration file.

```yaml
# /etc/traefik/dynamic/myapp.yml
http:
  routers:
    myapp:
      rule: "Host(`example.com`)"
      service: myapp
      tls:
        certResolver: letsencrypt
```

`http.services:` — Define a service pointing to a backend server.

```yaml
http:
  services:
    myapp:
      loadBalancer:
        servers:
          - url: "http://10.0.0.1:8080"
          - url: "http://10.0.0.2:8080"
```

`tls.certificates:` — Load custom TLS certificates from files.

```yaml
tls:
  certificates:
    - certFile: /etc/traefik/certs/example.com.pem
      keyFile: /etc/traefik/certs/example.com-key.pem
```

## Logging & Debugging

`log:` — Set the log level (DEBUG, INFO, WARN, ERROR).

```yaml
log:
  level: INFO
  filePath: /var/log/traefik/traefik.log
```

`accessLog: {}` — Enable access logging for all requests.

```yaml
accessLog:
  filePath: /var/log/traefik/access.log
  format: json
```

`ping: {}` — Enable the /ping health endpoint.

```yaml
ping:
  entryPoint: web
```

`metrics:` — Enable the Prometheus metrics endpoint.

```yaml
metrics:
  prometheus:
    entryPoint: metrics
    addEntryPointsLabels: true
    addServicesLabels: true
```

## Useful Router Rules

`` Host(`<domain>`) `` — Match requests by hostname.

```bash
Host(`example.com`)
```

`` Host(`<domain>`) || Host(`<domain2>`) `` — Match multiple hostnames.

```bash
Host(`example.com`) || Host(`www.example.com`)
```

`` PathPrefix(`<path>`) `` — Match requests by URL path prefix.

```bash
PathPrefix(`/api`)
```

`` Path(`<path>`) `` — Match an exact URL path.

```bash
Path(`/health`)
```

`` Headers(`<key>`, `<value>`) `` — Match requests by header value.

```bash
Headers(`X-Custom-Header`, `special-value`)
```

`` HostRegexp(`{subdomain:[a-z]+}.example.com`) `` — Match hostnames with a regular expression.

```bash
HostRegexp(`{subdomain:[a-z]+}.example.com`)
```

`` ClientIP(`<cidr>`) `` — Match requests from specific client IP ranges.

```bash
ClientIP(`10.0.0.0/8`)
```

<!-- PROSE:outro -->
## Conclusion

Traefik takes most of the manual proxy upkeep off your hands: new containers show up automatically as routers and services via labels, and Let's Encrypt certificates are issued and renewed without a cron job. Keep a clean separation between what is static (entry points, providers, resolvers) and what arrives dynamically (labels or the file provider) – that keeps your configuration manageable even with many services. And mind the security basics: never expose the dashboard unprotected, and mount the Docker socket read-only.

## Further Reading

- [Traefik – official documentation](https://doc.traefik.io/traefik/) – reference and manual
- [Traefik – GitHub repository](https://github.com/traefik/traefik) – source code and releases
<!-- PROSE:outro:end -->

## Related Commands

- [apache](https://www.jpkc.com/db/en/cheatsheets/web-servers/apache/) – classic web server, also usable as a reverse proxy
- [caddy](https://www.jpkc.com/db/en/cheatsheets/web-servers/caddy/) – web server with automatic HTTPS, similar approach
- [certbot](https://www.jpkc.com/db/en/cheatsheets/web-servers/certbot/) – manage Let's Encrypt certificates manually

