Traefik can act as your only entry point to your services, even if those services are running on different ports and protocols.
Let’s get Traefik installed and routing a request to a simple "hello world" web server.
First, we need a web server to route to. We’ll use a basic whoami service, which just echoes back information about the request it receives.
version: '3.8'
services:
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
This Docker Compose snippet defines a single service, whoami. The magic happens in the labels. These labels are how Traefik discovers and configures itself for this service.
traefik.enable=true: This tells Traefik to pay attention to this service.traefik.http.routers.whoami.rule=Host(\whoami.localhost`):This is the crucial routing rule. It tells Traefik to direct any incoming request with aHostheader matchingwhoami.localhost` to this service.traefik.http.routers.whoami.entrypoints=web: This specifies that this router should listen on thewebentrypoint (which we’ll define in Traefik’s configuration).traefik.http.services.whoami.loadbalancer.server.port=80: This tells Traefik which port on thewhoamicontainer to forward traffic to.
Now, let’s set up Traefik itself. We’ll run Traefik as a Docker service as well, using its official image and a simple configuration file.
Create a file named traefik.yml:
api:
dashboard: true
insecure: true
entryPoints:
web:
address: ":80"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
This configuration does a few things:
api.dashboard: trueandapi.insecure: true: Enables the Traefik dashboard on port 8080 without authentication, which is great for getting started.entryPoints.web.address: ":80": Defines an entrypoint namedwebthat listens on port 80 of the host machine. This is where external traffic will come into Traefik.providers.docker.endpoint: "unix:///var/run/docker.sock": Tells Traefik to connect to the Docker daemon to discover services.providers.docker.exposedByDefault: false: This is important for security. It means Traefik will only manage services that havetraefik.enable=trueexplicitly set in their labels.
Now, let’s combine these into a single docker-compose.yml file to launch both Traefik and our whoami service.
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--api.dashboard=true"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080" # For the dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.localhost`)"
- "traefik.http.routers.traefik.entrypoints=web"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.middlewares=traefik-auth" # Example, can be removed if insecure is fine
- "traefik.http.middlewares.traefik-auth.basicauth.users=user:$$apr1$$mR7s9p6a$$W.B1R.8d25/4w9v8m4N7a0" # user:password
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(\`whoami.localhost\`)"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
In this combined file, we’ve moved the Traefik configuration directly into the command arguments for simplicity. We also expose port 8080 for the dashboard and mount the Docker socket. Crucially, we’ve added labels to Traefik itself, making it discoverable by Traefik, so its dashboard can be accessed via traefik.localhost.
To make this work, you’ll need to edit your /etc/hosts file (or equivalent for your OS) to add these entries:
127.0.0.1 traefik.localhost whoami.localhost
Now, run docker compose up -d.
You should see Traefik and whoami starting up.
To test, open your browser and navigate to http://whoami.localhost. You should see the whoami output, showing details about your request. If you go to http://traefik.localhost, you’ll see the Traefik dashboard, which provides a live view of your configuration, routers, services, and more.
The fundamental mechanism at play is Traefik’s dynamic configuration discovery. By reading Docker labels, Traefik continuously monitors your containers. When a container with traefik.enable=true appears, Traefik automatically creates the necessary routing rules and service definitions based on the provided labels, injecting them into its active configuration without requiring a restart.
The most surprising thing about Traefik’s dynamic configuration is that it doesn’t just read the labels once. It actively watches the Docker API for changes. If you were to stop the whoami container, Traefik would automatically remove the whoami router and service from its configuration. If you start a new container with similar labels, Traefik will instantly pick it up and start routing traffic to it. This continuous reconciliation loop is what makes Traefik so powerful for dynamic container environments.
The next step is to explore how to add middleware for things like authentication, rate limiting, or request transformation.