If you want to follow along, you need to have the following:
- Docker. Version 20.10.13 is used in this tutorial.
- Docker-Compose. This tutorial uses version 1.29.2.
- You can use any other Linux-based operating system that allows you to run Docker and Docker-Compose freely. However, Fedora 35 host Docker was used in this article.
This tutorial also requires knowledge of basic Docker concepts as well as some Traefik terminology. I will provide enough explanation in this article to help you get through this post and also be able to set up and build more complex Traefik environments. For further explanation, consult the docs for Docker and Traefik.
Installing and configuring Traefik with Docker-Compose
The best way to see all enabled configuration options for a Traefik setup, while taking full advantage of native integration with Docker, is to use a Compose file. For this tutorial, we will use the file in the screenshot below. It is divided into two parts. The first part will focus on installing, running, and configuring Traefik statically. The second part will configure a backend Apache HTTPD service for Traefik via labels.
Walking through the Compose file
Every Compose file is made up of a group of services. In Docker-Compose, a service is a logical grouping of one or more containers that work together to provide specific functionality. The first service in the Compose file is the Traefik service, as shown in the snippet below.
traefik: image: "traefik:latest" ports: - "80:80" - "8080:8080" command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.web.address=:80" ports: - "80:80" - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock"
Understanding Traefik's static configuration
The Traefik service is backed by the latest traefik image and exposes ports 80 and 8080, which are mapped to ports 80 and 8080, respectively, on the host machine. You can see this in the Compose entries below.
traefik: image: "traefik:latest" ports: - "80:80" - "8080:8080"
Next, have a look at the Volumes entry. Volumes are external storage locations mapped into a mount point within a container. The contents of the volume are accessible in the container at the internal mount point, as though they were within the container.
The most critical volume that should be mounted is the host Docker socket. This gives Traefik access to the state of your Docker environment, which is required to serve dynamically as a reverse proxy. As in the snippet below, the host Docker socket(/var/run/docker.sock) is bind-mounted within the Traefik container at /var/run/docker.sock, according to the format.
[source]:[destination]; volumes: - "/var/run/docker.sock:/var/run/docker.sock"
Finally, we come to the command section, which includes command line options that are passed to the Traefik container when it is being created. Traefik expects configuration options that do not change frequently, also known as static configuration, to be present at startup. You can also set a static configuration either through a file or environmental variables—but not a combination of them.
To keep this guide concise, we use api.insecure=true to enable unencrypted HTTP connections to the dashboard, where you can monitor routing to your backend services alongside the state of Traefik. This dashboard will be available at port 8080. Even with HTTPS connections, the dashboard should be restricted to internal networks.
Second, the providers.docker=true setting enables Traefik to use the Docker provider to automatically discover and configure frontend and backend routes based on Docker containers running on the same host.
Finally, you need to set at least one entryPoint. EntryPoints in Traefik are ports where traffic to be proxied is expected to flow into your network. For this tutorial, an entryPoint called web is created for HTTP-only traffic at container port 80. This port can also be accessed at port 80 on the host machine. You can create another entryPoint for HTTPS traffic at port 443 if required. Just name it so that the configuration entry follows this syntax:
Together, the command section should resemble the screenshot below.
command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.web.address=:80"
Understanding Traefik dynamic configuration
At this point, running the Compose file should produce a ready Traefik instance. But you still need to use labels to define routing rules for containers hosting backend services. That is what you will do in this section.
The backend service for this tutorial is an Apache HTTPD service backed by the latest HTTPD image.
apache: image: "httpd:latest"
The next thing is the Labels section. In a Docker-Compose file, the labels section is used to attach metadata to a Docker container.
Let's take a deeper look at the first label.
This label instructs Traefik to create a router named apache that will route traffic for the hostname webserver.localhost to this container.
In Traefik architecture, you need at least an entryPoint, a router, and a service to which the traffic is routed. You have already configured an entryPoint and a router.
The second label defines the creation of a service named apache-serv that will be an exit point for the Apache router; that is, traffic from the entryPoint will be routed to the containers hosting the apache service.
The last label specifies the port to which to send matching traffic. For this tutorial, the default HTTPD port, 80, is used.
Technically, the last two labels are not required for this tutorial, as a default service is created by Traefik for each Docker service that is created. I added these redundant labels just to give you a hands-on introduction to service configuration. You can build on this knowledge to implement a more complex configuration. There is a list of labels for various custom behaviors that you can tweak for your use case.
Running the Compose file
Now that you have a working understanding of the Compose file, it is time to run it in your Docker environment.
Copy and paste the full file below into a new text file.
services: traefik: image: "traefik:latest" ports: - "80:80" - "8080:8080" command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.web.address=:80" ports: - "80:80" - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" apache: image: "httpd:latest" labels: - "traefik.http.routers.apache.rule=Host(`webserver.localhost`)" - "traefik.http.routers.apache.service=apache-serv" - "traefik.http.services.apache-serv.loadbalancer.server.port=80"
Save it as compose.yml.
Execute docker-compose, as shown below, in a terminal window to bring up the services in the background (-d):
docker-compose up -d
You should have feedback in your terminal, as follows, when the containers are up and running.
Open a browser window to http://webserver.localhost to confirm that you can reach the backend service successfully.
Also, bring up the dashboard at http://localhost:8080 to view stats on your Traefik setup.
Subscribe to 4sysops newsletter!
Installing and configuring Traefik can be a complex undertaking because you need to have a little container administration knowledge. This is one of the downsides of using Traefik. However, if Docker is your container environment, using Docker-Compose allows you to have all your configuration options in one location. In a few lines, it is straightforward to set up and customize components such as entryPoints, routers, and services. Once you climb the initial learning curve, you can enjoy all the benefits of Traefik, such as minimal configuration, automatic SSL termination, and automatic service discovery.