Learn Traefik - Docker Provider - Labels & Discovery
Episode 5 of 31

Learn Traefik - Docker Provider - Labels & Discovery

This episode unlocks Traefik's service discovery power through the Docker Provider: enabling the provider, Docker socket access, the traefik.http label structure, basic routing with Host and Path, load balancer service configuration, and how containers that start and stop are updated automatically.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Introduction

This is the episode that most sets Traefik apart from conventional proxies: auto-discovery. After reading this episode, you will run docker compose up -d and Traefik will automatically know how to route the new container — no configuration editing, no reload, no restart.

The way it works is through the Docker Provider and labels. Traefik reads the Docker socket, finds containers marked with specific labels, then translates those labels into routers, services, and middlewares in real time. Episode 5 unpacks this mechanism from the start all the way to correct routing practices.

Setting Up the Docker Provider

Enabling the Provider and Accessing the Socket

The Docker Provider is enabled in the static configuration. The key is mounting the Docker socket into the Traefik container — this is where Traefik observes the container world:

Static config for the Docker provider
providers:
  docker:
    exposedByDefault: false
    watch: true

The endpoint line does not need to be written because the Docker provider's default already points to the daemon socket unix:///var/run/docker.sock. If your socket is somewhere else, add an endpoint line as needed. Two settings you must understand:

  • exposedByDefault: false: only containers with the traefik.enable=true label are routed. The value true (default) routes all containers — dangerous because unknown containers end up exposed.
  • watch: true: Traefik continuously monitors Docker events. When a container starts, stops, or restarts, the configuration updates automatically.

Mount the socket with the read-only flag for security:

Compose: mount the Docker socket
services:
  traefik:
    image: traefik:v3
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./config/traefik.yml:/etc/traefik/traefik.yml:ro

Docker Label Structure

Systematic Label Names

All dynamic configuration from Docker is written as labels with the traefik. prefix. The basic pattern:

Traefik label pattern
traefik.enable
traefik.http.routers.<name>.rule
traefik.http.routers.<name>.service
traefik.http.routers.<name>.middlewares
traefik.http.services.<name>.loadbalancer.server.port
traefik.http.middlewares.<name>.<type>.<options>

Labels are grouped by component type, then component name, then configuration. A complete example of a backend container:

Complete labels on the app service
services:
  app:
    image: nginx:alpine
    labels:
      - traefik.enable=true
      - traefik.http.routers.app.rule=Host(`app.localhost`)
      - traefik.http.routers.app.entrypoints=web
      - traefik.http.routers.app.service=app-svc
      - traefik.http.services.app-svc.loadbalancer.server.port=80

The app container above produces a router named app and a service named app-svc pointing to container port 80. Accessing http://app.localhost will reach NGINX. Router and service naming is free, as long as it is consistent across labels.

Basic Routing

Host, Path, and Combined Rules

Rules are the heart of routing. The most common examples:

  • Host(app.localhost): matches a specific host.
  • Path(/api): matches the exact path /api.
  • PathPrefix(/api): matches all paths starting with /api.
  • Method(GET): matches a specific HTTP method.

Rules can be combined with logical operators. The && (AND) and || (OR) operators plus parentheses for grouping will be fully covered in episode 6. The combination example below shows two routes in a single container:

Combined rule with a prefix
services:
  api:
    image: myapi:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.api-pub.rule=Host(`api.localhost`) && PathPrefix(`/v1`)
      - traefik.http.routers.api-pub.entrypoints=web
      - traefik.http.routers.api-pub.service=api-svc
      - traefik.http.services.api-svc.loadbalancer.server.port=3000

Entrypoints and Priority

A router must declare which entrypoint it serves. If omitted, the router applies to all entrypoints — often causing unexpected conflicts. For priority between overlapping routers, Traefik calculates it automatically based on rule length; manual settings will be covered in episode 6.

Service Configuration

Load Balancer and Health Checks

A service defines the backend. In Docker, the backend automatically refers to the container in question; you just need to specify its internal port. Traefik v3 also supports health checks to remove unhealthy backends:

Service with a health check
services:
  api:
    image: myapi:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.api.rule=Host(`api.localhost`)
      - traefik.http.routers.api.service=api-svc
      - traefik.http.services.api-svc.loadbalancer.server.port=3000
      - traefik.http.services.api-svc.loadbalancer.healthcheck.path=/health
      - traefik.http.services.api-svc.loadbalancer.healthcheck.interval=10s

If the /health health check fails, Traefik removes that container from the load balancing rotation until it is healthy again. If all backends fail, Traefik returns HTTP 503. The same mechanism applies when a container is scaled — it automatically enters and leaves the rotation.

Auto-Discovery in Practice

Watching Configuration Change

To prove its dynamic nature, run the following experiment:

Container starts and routes appear automatically
docker compose up -d traefik
docker compose up -d app
curl -H "Host: app.localhost" http://localhost
docker compose scale app=2

Run the commands above one by one while watching the HTTP Routers tab in the dashboard or calling the API:

Inspecting routers via the API
curl -s http://localhost:8080/api/http/routers | head -n 30

When app is scaled to 2, Traefik automatically adds the second server to the service without a restart. The JSON response from the API shows the real-time state. The curl command is the fastest way to verify that discovery works as expected.

Warning

Never mount the Docker socket into a container you do not trust. Anyone with socket access can fully control the Docker daemon. A read-only mount is the minimum, not a security guarantee.

Closing

Key takeaways:

  • The Docker Provider reads the Docker socket to find and route containers.
  • exposedByDefault: false prevents containers without labels from being exposed.
  • Labels traefik.http.routers.<name>.* and traefik.http.services.<name>.* build routing.
  • Host and PathPrefix rules are the basis of matching; they can be combined with operators.
  • Services support health checks so unhealthy backends are automatically removed.
  • Auto-discovery runs in real time: scaling up immediately updates the load balancer.

In episode 6 next we will go deeper into routers and rules — all available matchers such as HostRegexp, Method, Headers, and Query, logical operators, priority rules, and examples of complex rule combinations. After this, you can design routing for real-world scenarios.

Learn Traefik - Docker Provider - Labels & Discovery | Learn Traefik