Traefik logo

Traefik is a leading reverse proxy and load balancer for cloud-native operations and containerized workloads. It functions as an edge router that publishes your services to the internet.

Traefik routes requests to your containers by matching request attributes such as the domain, URL, and port. The proxy incorporates automatic service discovery so you can add new containers in real-time, without restarting the Traefik service.

In this guide, we’ll put together a simple Traefik v2 deployment that will publish multiple Docker containers. This lets you use one Docker installation to provide several services over the same port, such as a web application, API, and administration panel.

Getting Started

It’s easiest to deploy Traefik using its own Docker image. We’ll assume you’re running Traefik with Docker for the remainder of this guide. Single-file binaries are available as an alternative option if you’d prefer Traefik to sit outside your Docker installation.

You must create a config file before you can start using Traefik. Add the following content to a traefik.toml file – we’ll explain what it does below:

[entryPoints]
  [entryPoints.http]
      address = ":80"
      [entryPoints.http.http.redirections.entryPoint]
          to = "https"
          scheme = "https"
  [entryPoints.https]
      address = ":443"
 
[providers]
  [providers.docker]
    network = "traefik"
Advertisement

This config file configures Traefik with two “entrypoints.” Entrypoints describe how requests reach the Traefik service. HTTP and HTTPS entrypoints are created to listen on ports 80 and 443 respectively. In the case of an HTTP request, a redirection rule is used to forward it to the https entrypoint instead. Remove the redirection section if you want to be able to serve content over plain HTTP.

The “providers” section configures the sources that define your network routes. Providers are simply infrastructure components which can issue Traefik with routing instructions. If you wanted to, you could write a custom HTTP API endpoint to define your routes.

In this example, we’re keeping it simple and using the docker provider. This monitors the Docker containers running on your host. When a new container appears with Traefik-specific labels, those values will be used to set up a route to the container. The containers will need to be attached to the traefik Docker network for this to work as that’s the network specified in the config file. Create the network now:

docker network create traefik

Starting Traefik

Now you’re ready to start Traefik! Deploy a new container with the Traefik image. Bind ports 80 and 443 to your host, allowing Traefik to listen for incoming requests. You should also join the container to the traefik network created earlier.

 

Mount your host’s Docker socket into the Traefik container with the -v flag. This gives Traefik the ability to access other containers running on your host, enabling automatic detection of routes via the docker provider set up in your config file. The config file itself is mounted to /traefik.toml inside the Traefik container.

docker run -d 
  -p 80:80 
  -p 443:443 
  -v $PWD/traefik.toml:/traefik.toml 
  -v /var/run/docker.sock:/var/run/docker.sock 
  --name traefik 
  --network traefik 
  traefik:2.6

Next start a couple of containers to test that Traefik is working:

docker run -d 
  --label traefik.http.routers.apache.rule=Host(`apache.example.com`) 
  --name apache 
  --network traefik 
  httpd:latest

docker run -d 
  --label traefik.http.routers.nginx.rule=Host(`nginx.example.com`) 
  --name nginx 
  --network traefik 
  nginx:latest
Advertisement

Make sure you’ve added DNS records for apache.example.com and nginx.example.com that map to your Traefik host. You should be able to visit those domains in your browser to see the default Apache and NGINX landing pages respectively. The two containers are joined to the Traefik network; their traefik.http.routers labels set up basic routes that match incoming requests by the value of their Host header.

Routing Traffic

Traefik supports several different “matchers” for routing your traffic. We’ve used the Host matcher above but you can also route by HTTP method, headers, URI, IP address, and query string parameters. Add multiple matchers to your containers to build up more complex routing rules.

Traefik also supports middlewares that let you modify the request before it reaches your services. You might want to add a prefix, adjust headers, or apply Basic Authentication at the proxy level. Here’s an example of using the Headers middleware to add an extra X-Proxied-By request header:

docker run -d 
  --label traefik.http.routers.nginx.rule=Host(`nginx.example.com`) 
  --label traefik.http.middlewares.demo.headers.customrequestheaders.X-Proxied-By=traefik
  --name nginx 
  --network traefik 
  nginx:latest

Traefik routes traffic to the exposed ports of your containers. You can specify a different port by setting the traefik.http.services.<demo-service>.loadbalancer.server.port=8080 label.

Adding SSL

Next you should add SSL to ensure your traffic is fully protected. Traefik includes Let’s Encrypt integration so we’ll that use now to automate certificate generation.

Add the following section to your traefik.toml file:

[certificatesResolvers.lets-encrypt.acme]
  email = "you@example.com"
  storage = "/acme.json"
  [certificatesResolvers.lets-encrypt.acme.tlsChallenge]

This configures Traefik to use the Let’s Encrypt ACME provider when resolving certificate requests. Make sure to replace the email address with your own so you receive any certificate expiry reminders sent by Let’s Encrypt. The tlsChallenge section defines how certification verification occurs; leaving it empty will use the default flow of serving a unique file which Let’s Encrypt will request and validate during certificate issuance.

Advertisement

Restart or replace your Traefik container to apply the new configuration. You should also mount a new file to /acme.json inside the container – Traefik will use this to store certificates.

docker run -d 
  -p 80:80 
  -p 443:443 
  -v $PWD/acme.json:/acme.json 
  -v $PWD/traefik.toml:/traefik.toml 
  -v /var/run/docker.sock:/var/run/docker.sock 
  --name traefik 
  --network traefik 
  traefik:2.6

Using the Dashboard

Traefik includes a web UI that offers a graphical view of the endpoints, providers, and services (containers) active in your deployment. You can expose the UI by setting up a route for it in your config file.

First modify your existing traefik.toml with the following section:

[api]
  dashboard = true
 
[providers.file]
  filename = "/traefik_dashboard.toml"

Next create traefik_dashboard.toml with the following content:

[http.middleware.dashboard_auth.basicAuth]
  users = [
    "admin:$123..."
  ]
 
[http.routers.api]
  rule = "Host(`traefik.example.com`)"
  entrypoints = ["https"]
  middlewares = ["dashboard_auth"]
  service = "api@internal"
  [http.routers.api.tls]
    certResolver = "lets-encrypt"

The new file is needed as Traefik as doesn’t support “dynamic” configuration (services and routers) alongside the “static” values in your main traefik.toml. The dashboard config file manually defines a route that maps traefik.example.com to the internal web UI service. The providers.file line added to traefik.toml registers the new route definition with the file provider.

Use htpasswd to generate a set of HTTP Basic Auth credentials. Add the generated string to the users array in the dashboard_auth middleware. You’ll need to use this username and password to access the dashboard.

sudo apt install apache2-utils
htpasswd -nb admin your_password

# Outputs admin:$123...

Now restart Traefik with your updated configuration, remembering to mount the new traefik_dashboard.toml file too:

docker run -d 
  -p 80:80 
  -p 443:443 
  -v $PWD/acme.json:/acme.json 
  -v $PWD/traefik.toml:/traefik.toml 
  -v $PWD/traefik_dashboard.toml:/traefik_dashboard.toml 
  -v /var/run/docker.sock:/var/run/docker.sock 
  --name traefik 
  --network traefik 
  traefik:2.6

You should be able to access the dashboard by heading to traefik.example.com in your browser. If you don’t want to expose the web UI as a route and will always access it from your local machine, you can publish port 8080 on your Traefik container instead. Modify your traefik.toml file with the following section:

[api]
  dashboard = true
  insecure = true
docker run -d 
  -p 8080:8080 
  -p 80:80 
  -p 443:443 
  -v $PWD/acme.json:/acme.json 
  -v $PWD/traefik.toml:/traefik.toml 
  -v /var/run/docker.sock:/var/run/docker.sock 
  --name traefik 
  --network traefik 
  traefik:2.6
Advertisement

This will let you access the dashboard via http://localhost:8080. This approach should not be used in secure production environments but makes for quicker set up of local experiments.

Conclusion

Traefik is a versatile reverse proxy solution for your containers. In this article, we’ve only covered the most fundamental of its capabilities. Beyond basic use with Docker, Traefik also works with leading container orchestration solutions including Kubernetes, Docker Swarm, and Mesos.

Traefik provides a REST API as well as metrics in formats understood by Prometheus, InfluxDB, Datadog, and Statsd. These capabilities let you automate and instrument Traefik deployments alongside the other infrastructure components in your stack. It’s an ideal way to publish containerized workloads to the world without using a full orchestration solution.

Profile Photo for James Walker James Walker
James Walker is a contributor to How-To Geek DevOps. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows, using technologies including Linux, GitLab, Docker, and Kubernetes.
Read Full Bio »