DEV Community

Jawira Portugal
Jawira Portugal

Posted on

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.

Image description

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
Enter fullscreen mode Exit fullscreen mode

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:
Enter fullscreen mode Exit fullscreen mode

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`)'
Enter fullscreen mode Exit fullscreen mode

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 in docker-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 address 127.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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Let's execute our demo project:

$ docker compose -p foo up -d
Enter fullscreen mode Exit fullscreen mode

Now, if we open http://web.foo.localhost we will see Apache's welcome message:

Image description

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 simple add a new label:

# ...
  web:
    image: httpd
    labels:
      - traefik.enable=true
+     - traefik.http.routers.foo-project.rule=Host(`my-foo.localhost`)
# ...
Enter fullscreen mode Exit fullscreen mode

To make changes take effect we have to launch again our project using docker compose -p foo up -d. This is the result:

Image description

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.

Discussion (2)

Collapse
ben profile image
Ben Halpern

Great post

Collapse
loismyers profile image
LoisMyers

This is a great tutorial on getting people onboard. Thanks for writing this post . spell to make someone like you