Træfik is an open-source routing service that can be used when communication is needed between containers or services, such as in a Kubernetes environment.
In my case, I wanted to deploy multiple backend services on a single VPS (Virtual Private Server), so I needed to route incoming DNS requests to the appropriate service. While this can be done using services like Nginx or Apache, these solutions can be cumbersome and complex when deploying multiple containerized services. Træfik simplifies and streamlines this process.
In this article, I’ll briefly explain how to use Træfik with a simple example.
To summarize, Træfik can be understood through four main concepts:
Since this article focuses on docker-compose
, we’ll let Træfik handle the services part under-the-hood. In short, you only need to define where the request comes from, how it should be processed, and where it should be routed.
Installing træfik in a docker environment is as simple as running the following command:
docker run traefik[:version]
In this case, the container will start and load settings from a traefik.yml
configuration file, so the file needs to be created beforehand.
Alternatively, you can define the service using docker-compose
like this:
name: traefik-example
services:
traefik:
image: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080" # For accessing the internal dashboard; can be enabled with --api-insecure
command:
- "--api-insecure"
- "--providers.docker"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# For Docker internal monitoring
In this setup, most of the configuration is handled via the command:
and labels:
fields, allowing Træfik to interact directly with Docker.
Let’s connect Træfik with the services we want to route traffic to. Suppose you have two personal Docker Hub repositories: myRepo/backendapi
and myRepo/reactserver
.
We’ll define the services like this:
services:
backendapi:
image: myRepo/backendapi
restart: always
ports:
- "80:80"
reactserver:
image: myRepo/reactserver
restart: always
ports:
- "3000:3000"
In this example, backendapi
uses port 80, and reactserver
uses port 3000 internally.
Goals:
reactserver
, and both HTTP/HTTPS for backendapi
.Assuming both services don’t support HTTPS by default, let’s start by adding two entrypoints to the Træfik service:
command:
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
Next, we’ll define routers for each container to route incoming traffic. Use the following label format:
traefik.http.routers.<router-name>.rule=...
This defines the router’s name and rule it will use to process incoming requests.
Let’s say:
api.domain.com
goes to backendapi
domain.com
goes to reactserver
backendapi:
...
labels:
- "traefik.http.routers.backendrouter.rule=Host(`api.domain.com`)"
reactserver:
...
labels:
- "traefik.http.routers.frontendrouter.rule=Host(`domain.com`)"
Since reactserver
should use HTTPS and backendapi
should support both HTTP and HTTPS, assign the appropriate entrypoints:
We’ll also remove the exposed ports from the containers and instead inform Træfik of the internal port using:
traefik.http.services.<service-name>.loadbalancer.server.port=[port]
So now,
backendapi:
...
labels:
- "traefik.http.routers.backendrouter.rule=Host(`api.domain.com`)"
- "traefik.http.routers.backendrouter.entrypoints=web,websecure"
- "traefik.http.services.backendapi.loadbalancer.server.port=80"
reactserver:
...
labels:
- "traefik.http.routers.frontendrouter.rule=Host(`domain.com`)"
- "traefik.http.routers.frontendrouter.entrypoints=websecure"
- "traefik.http.services.reactserver.loadbalancer.server.port=3000"
This sets up routing rules for both services based on the entrypoint and host name.
TLS Setup for HTTPS
First, obtain an origin TLS certificate and private key from your DNS provider, and store them securely (e.g., in /traefik/certificates
).
Mount the certificates so Træfik can access them:
volumes:
- ./traefik/certificates:/etc/traefik/certificates
Since træfik does not yet support directly configuring tls certificates within docker-compose.yml
, a dynamic configuration file (e.g., certificates.yml
) must be created like so:
# certificates.yml
tls:
certificates:
- certFile: /etc/traefik/certificates/<certificate>.crt
keyFile: /etc/traefik/certificates/<certificate>.key
stores:
default:
defaultCertificate:
certFile: /etc/traefik/certificates/<certificate>.crt
keyFile: /etc/traefik/certificates/<certificate>.key
Also mount the configuration directory:
volumes:
- ./traefik/certificates:/etc/traefik/certificates
- ./traefik/config:/etc/traefik
Then, instruct Træfik to load the config file:
command:
- "--api-insecure"
- "--providers.docker"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--providers.file.directory=/etc/traefik"
Finally, enable TLS by default for HTTPS traffic:
- "--entrypoints.websecure.http.tls=true"
Happy shipping 🙂