Defining dynamic Host rule in Traefik V2
Traefik is a reverse http proxy, it works specially well with docker and docker-compose environments. Traefik will receive all your incoming web requests and redirect them to Docker containers.
In order to redirect your requests, Traefik will use a router to identify the appropriate web server.
In this article I show you how I configured a default “Host rule” for my development environment. This rule will automatically add a rule for any service.
http://<service>.<project>.localhost
I assume you already have some experience with Docker and Traefik.
Traefik configuration
First install Traefik. Let’s create a new project with the following structure:
traefik/
└── docker-compose.yaml
You only need one single file to start using Traefik. This is the content
of traefik/docker-compose.yaml
:
version: '3.7'
services:
traefik:
image: traefik:v2.7
restart: always
command:
- '--api.insecure=true'
- '--providers.docker.exposedByDefault=false'
- '--providers.docker.network=traefik_default'
- '--providers.docker.defaultRule=Host(`{{ index .Labels "com.docker.compose.service" }}.{{ index .Labels "com.docker.compose.project" }}.localhost`)'
labels:
- 'traefik.http.services.traefik-traefik.loadBalancer.server.port=8080'
- 'traefik.enable=true'
ports:
- '80:80'
- '8080:8080'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
networks:
- default
networks:
default:
This is the most important command option when creating dynamic rules:
- '--providers.docker.defaultRule=Host(`{{ index .Labels "com.docker.compose.service" }}.{{ index .Labels "com.docker.compose.project" }}.localhost`)'
Let’s see what the previous line does:
- –providers.docker.defaultRule: this is the rule to be used if container doesn’t define one.
- Host(): the requested domain will be used for routing.
{{ index .Labels "com.docker.compose.service" }}
: this represents the service name, the one you define indocker-compose.yaml
.{{ index .Labels "com.docker.compose.project" }}
: this placeholder will be replaced with project name. By default, the project name is the directory name, you can also specify this value with-p <project>
option.- Finally
.localhost
is a reserved domain, it will always point to the loopback address127.0.0.1
. Using.localhost
, you will not need to add your development domains to/etc/hosts
.
Start Traefik with the following command:
$ docker compose -p traefik up -d
Traefik is up and running now.
Creating a sample project
We will create a demo project to check if our dynamic rules work properly. This
is the structure of foo
project:
foo/
└── docker-compose.yaml
We define an Apache server within foo/docker-compose.yaml
:
version: "3.7"
services:
web:
image: httpd
labels:
- traefik.enable=true
networks:
- default
- traefik_default
networks:
default:
traefik_default:
external: true
Let’s execute our demo project:
$ docker compose -p foo up -d
Now, if we open http://web.foo.localhost
we will see Apache’s welcome message:
Using a custom rule
We can also specify a custom rule for a service, this custom rule will override the default rule.
For example, we want to use my-foo.localhost
, to do so we simply add a new label
:
# ...
web:
image: httpd
labels:
- traefik.enable=true
+ - traefik.http.routers.foo-project.rule=Host(`my-foo.localhost`)
# ...
To make changes take effect we have to launch again our project
using docker compose -p foo up -d
. This is the result:
As you can see everything works as expected.
Conclusion
Traefik is a highly configurable reverse proxy. You only need one line of code to have dynamic domains, these domains are well suited for development environments.
If you use .localhost
tld, you won’t need to declare your domains
within /etc/hosts
.