How to Use Traefik as a Reverse Proxy for Docker Containers on Ubuntu 18.04

Barry

Introduction

One of the best way for running web applications is with the use of Docker. Also if you want to run several applications you can use the similar which is known as the Docker host. In this scenario you will have to set a reverse proxy in order to expose the Docker which is also an eminent way for running web applications for production ,however you can also run various a lot of applications at the same time on Docker host . You will have to set a reverse proxy because you will show up ports 80 and 443 all over.
A reverse proxy Traefik, which is Docker aware helps in self-monitoring of the dashboard. In this particular blog you will get to know how to use Traefik to route requests to two different web application containers: a WordPress container and an Adminer container, carrying each to MySQL database.

Configuring and Running Traefik

In order to run Traefik in a Docker container, you will have to use the official Docker image. But before you get your Traefik container running and up you will have to make a configuration file and you will have to secure it with a password which is encrypted password in order to run the monitoring dashboard.

JOIN OUR NEWSLETTER
Not Every One Focuses On Your Requirements! Get What You Want- Revenue & Ranking Both. Make Money While Stepping Up The Ladder Of SERPs.
We hate spam. Your email address will not be sold or shared with anyone else.

If you want to create this encrypted password you will have to use the htpasswd utility. Now you will have to install the utility that is already existing in the apache2-utils package:

$ sudo apt-get install apache2-utils

Now create the password with the help of htpasswd. Now you will have to replace it with secure_password with your preferable password you will like to use for the Traefik admin user:

htpasswd -nb admin secure_password

After this you will be getting a output similar to the following:

Output
admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

Now in order to set up HTTP Basic Authentication for the Traefik health check and monitoring output you will have to use this following output.

Now create a new configuration file named as traefik.toml in order to configure the Traefik server. TOML can be used which is a standardized configuration language and which almost alike to INI files. In order to configure this file you will have to configure the Traefik server and various integrations, or providers which you want to use.

Then you need to open your new preferable text editor or nano:

nano traefik.toml

Now you will have to add entry points http and https, which will be accessed by default by all other backends:

traefik.toml
defaultEntryPoints = ["http", "https"]

And then later on you will, have to configure the http and https entry points later on in this particular file. After this you will have to configure the api provider and now here you will have to paste the output that you have from htpasswd command:

traefik.toml
...
[entryPoints]
  [entryPoints.dashboard]
    address = ":8080"
    [entryPoints.dashboard.auth]
      [entryPoints.dashboard.auth.basic]
        users = ["admin:your_encrypted_password"]

[api]
entrypoint="dashboard"

You will have to set the dashboard to run on the port 8080.

The entrypoints.dashboard is configured by connecting with the api provider and the HTTP Basic Authentication for the dashboard is configured by the entrypoints.dashboard.auth.basic. You will have to use the output obtained from the htpasswd command which you have accessed shortly.

You will have to define HTTP and HTTPS communication apart from the first entryPoint. The addresses that the Traefik and proxied can access with is configured by the entrypoint section. You need to add these following lines as mentioned below:

traefik.toml
...
  [entryPoints.http]
    address = ":80"
      [entryPoints.http.redirect]
        entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]
...

The port 80 is handled by the http entry point, and for TLS/SSL 443 port is used by the https entry point. You will have to redirect on port 80 all the traffic, to the https entry point for force protecting the connections for all the requests and then you will have to add the following section in orderto configure Let’s Encrypt certificate support for Traefik:

traefik.toml
...
[acme]
email = "your_email@your_domain"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
  [acme.httpChallenge]
  entryPoint = "http"

ACME is type of protocol used for communicating with Let’s encrypt in order to manage certificates, and thus this section is called acme. You need to have a valid email address in order to set that as your email key because Let’s Encrypt service requires registration and for having Traefik generate certificates for your hosts. You then need to particularize that we need to store the details those we will achieve from Let’s Encrypt inside the JSON file which is called acme.jso. The entryPoint key handling port 443 now needs to be pointed out by the entry point which in here is the https entry point.

The way of generating certificates is organized by the key onHostRule. As soon as your containers are created with particular host names you will have to fetch the certificates.

Through the http entry point you will have to configure acme.httpChallenge as it will allow you to particularize the way Let’s Encrypt will do the verification of the certificate which will generated.

And then finally you will have to configure the docker provider by adding on these commands:

traefik.toml
...
[docker]
domain = "your_domain"
watch = true
network = "web"

The Traefik is enabled to act as a proxy in front of Docker containers by the docker provider. You need to configure the provider in order to watch for new containers available on the web network in and then reveal them as subdomains of your_domain.

Now in this scenario your traefik.toml should have the following contents:

traefik.toml
defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.dashboard]
    address = ":8080"
    [entryPoints.dashboard.auth]
      [entryPoints.dashboard.auth.basic]
        users = ["admin:your_encrypted_password"]
  [entryPoints.http]
    address = ":80"
      [entryPoints.http.redirect]
        entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = "your_email@your_domain"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
  [acme.httpChallenge]
  entryPoint = "http"

[docker]
domain = "your_domain"
watch = true
network = "web"

After this you will have to save the file and exit the editor and also with all these just on place you can now fire up the Traefik.

Running the Traefik Container

Now you will have to create a Docker network in order to share proxy with the containers .The applications those are accessed with the Docker Compose , for them the Docker network is very necessary. You can call this network web.

$ docker network create web

As soon as the Traefik container begins you will have to add it to your network and then later for Traefik and proxy to.

Now you will have to create an empty file where you will have to hold your Let’s encrypt information. You will have to share this container in order to make it available, so that Traefik can use it:

$ touch acme.json

If there is latest read and write access inside of the container then only Traefik will be able to use this file. For doing this you need to lock down the permissions on acme.json in order to look into the fact that the owner has only the permission to read and write.

$ chmod 600 acme.json

As soon as the file gets passed to Docker, the owner will have to automatically change to the root user inside the container.

Now you will have to generate the Traefik container with this following command:

$ docker run -d \
$   -v /var/run/docker.sock:/var/run/docker.sock \
$   -v $PWD/traefik.toml:/traefik.toml \
$   -v $PWD/acme.json:/acme.json \
$   -p 80:80 \
$   -p 443:443 \
$   -l traefik.frontend.rule=Host:monitor.your_domain \
$   -l traefik.port=8080 \
$   --network web \
$   --name traefik \
$   traefik:1.7.2-alpine

You will have break down the command as it is bit long.

You will have to use the  -d flag in order to access the container in the background just like a daemon. Then you will have to shift your docker.sock file into the container for the traefik process to listen for the changes to the containers. You will also have to share the traefik.toml configuration file and the acme.json file which you have created inside the container.

You will now have to map ports :80 and :443 of your Docker host to the exact same ports in the Traefik container so Traefik will be receiving all HTTP and HTTPS traffic from the server.

Now you will have to set up two Docker labels which will ask the Traefik to direct traffic to the hostname monitor.your_domain to port :8080 within the Traefik container, revealing the monitoring dashboard.

Next you will have to set the network of the container to web, and we then you will have to name the container traefik.

Now after this you will have to use the traefik:1.7.2-alpine image for this container, just because it is a small container.

The command is the traefik binary within the container. A Docker image’s ENTRYPOINT is a command that always runs when a container is created from the image. So you can now pass on extra arguments to this command when you are about to launch the container, however you have already configured all your setting in the traefik.toml file.

With the container started, you now have a dashboard you can access to see the health of your containers. You can also use this dashboard to visualize the frontends and backends that Traefik has registered. Access the monitoring dashboard by pointing your browser to https://monitor.your_domain. You will be prompted for your username and password, which are admin and the password you configured in Step 1.

As soon as you log in you will be able to see an interface which will be quite similar to this:

Image Source: https://do.co/2C3tGq7

You need to leave this window open, though there is not much to see still, and then you will see the contents changing as you add on containers for Traefik with which you can work with.

You are now having a running Traefik proxy, which is configured to collaborate with Docker, and is also ready to monitor the other Docker containers. Now you will have to start some containers for traefik so that can act as a proxy.

Registering Containers with Traefik

You are now ready to run applications behind the Traefik container and you will have to launch the following containers behind Traefik:

  • The official WordPress image which is used by a blog.
  • The official Adminer Image used by a database management server.

Now using a docker-compose.yml file you will have to manage both of these applications with the help of Docker Compose. now you will have to open the docker-compose.yml file in your editor:

$ nano docker-compose.yml

Now you will have the following commands to the file in order to particularize the version and the networks you will use:

docker-compose.yml
version: "3"

networks:
  web:
    external: true
  internal:
    external: false

you will have to use Docker Compose Version 3 as it is the completely exclusive version of the Compose File Format.

If you want your Traefik to recognize your application you need check that your applications are the part of the same network also as the network has been created manually by you, you will have to pull it particularizing the name of the network of web and setting external to true. In order to connect your revealed containers to a database container which can’t be exposed through Traefik you need to define another network which is known as internal.

Now you will have to define each of our services, each at a time. Now you will have to begin with the blog container, which will based on the official WordPress image and you will have add this configuration into the file:

docker-compose.yml
version: "3"
...

services:
  blog:
    image: wordpress:4.9.8-apache
    environment:
      WORDPRESS_DB_PASSWORD:
    labels:
      - traefik.backend=blog
      - traefik.frontend.rule=Host:blog.your_domain
      - traefik.docker.network=web
      - traefik.port=80
    networks:
      - internal
      - web
    depends_on:
      - mysql

The environment variables get particularized by the environment keys which will be inside the container. If you are not setting any value for WORDPRESS_DB_PASSWORD, you are asking the Docker Compose in order to get the value from your shell and then shift it after you create the container. Now you will to define this environment in your shell before you begin the containers. Through this process you do not hard-code the passwords into the configuration file.

The configuration values for Traefik will be specified in the labels section as this knows how to treat containers, However Docker labels has no such function as in themselves but Traefik reads these. Here is the list of activities that the labels perform:

  • The name of the backend service is specified by traefik.backend which helps to point out the original blog container.
  • The Traefik is told by the traefik.frontend.rule=Host:blog.your_domain to examine the host requested and then if the pattern of the blog.your_domain matches it will help to route the Traefik to the blog container.
  • In order to find the internal IP for the container traefik.docker.network=web specifies which network should be looked under for Traefik. As the Traefik container have the access to all the Docker info, it should definitely take the IP for the internal network, if you have not specified this.
  • The exposed ports which must be used by Traefik to route traffic to the container is specified by traefik.port

All the traffic that has been sent to your Docker host’s port 80 will be routed to the blog container with the help of this configuration.

Now you need to assign this particular container for two different networks for making it easy for the Traefik to find it through web network and it can connect through the network and it is also able to connect with databade container through the internal network.

Finally, the Docker Compose is asked by the depends_on key that whether this container needs to start after its dependencies are correctly accessing, as WordPress will need a database to run and you should access your mysql container before you begin your blog container.

Now you will have to configure the MySQL service. And you also need to add this configuration to your file:

docker-compose.yml
services:
...
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD:
    networks:
      - internal
    labels:
      - traefik.enable=false

Here the official MySQL 5.7 image has been used for this container. Soon you will also find that you are using an environment item without a value. You will have to set the MYSQL_ROOT_PASSWORD and WORDPRESS_DB_PASSWORD variables to the same value in order to make sure that your WordPress container is able to connect with the MySQL. You will have to assign the container to the internal network as we do not want to reveal the mysql container to Traefik or globally. The process will keep on revealing a frontend for the mysql container by default as Traefik has access to the Docker socket, so you will have to add the label traefik.enable=false in order to specify that Traefik is not revealing this container.

Finally, you will have to add this configuration to define the Adminer container:

docker-compose.yml
services:
...
  adminer:
    image: adminer:4.6.3-standalone
    labels:
      - traefik.backend=adminer
      - traefik.frontend.rule=Host:db-admin.your_domain
      - traefik.docker.network=web
      - traefik.port=8080
    networks:
      - internal
      - web
    depends_on:
      - mysql

The Adminer image is the basic of this container also the configuration for this containers matches what you will be using for the blog container. But if you are navigating all of the traffic to port 80, on your Docker host to the blog container, you will have to configure this container, in order to make it to your adminer container, you will have to configure the container differently. The line traefik.frontend.rule=Host:db-admin.your_domain asks Traefik to test the requested host, and if you find it matching the pattern of db-admin.your_domain, the traffic will be routed to the adminer container by the Traefik.

At this certain scenario, docker-compose.yml must have these following contents:

docker-compose.yml
version: "3"

networks:
  web:
    external: true
  internal:
    external: false

services:
  blog:
    image: wordpress:4.9.8-apache
    environment:
      WORDPRESS_DB_PASSWORD:
    labels:
      - traefik.backend=blog
      - traefik.frontend.rule=Host:blog.your_domain
      - traefik.docker.network=web
      - traefik.port=80
    networks:
      - internal
      - web
    depends_on:
      - mysql
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD:
    networks:
      - internal
    labels:
      - traefik.enable=false
  adminer:
    image: adminer:4.6.3-standalone
    labels:
      - traefik.backend=adminer
      - traefik.frontend.rule=Host:db-admin.your_domain
      - traefik.docker.network=web
      - traefik.port=8080
    networks:
      - internal
      - web
    depends_on:
      - mysql

Now you will have to exit the text editor and before that you will have save the file.

Now you will have to set the values in your shell for the WORDPRESS_DB_PASSWORD and MYSQL_ROOT_PASSWORD variables before you begin your containers:

$ export WORDPRESS_DB_PASSWORD=secure_database_password
$ export MYSQL_ROOT_PASSWORD=secure_database_password

Now you will have to exchange secure_database_password with your preferable database password. You will have to use the same password in both the cases; for both both WORDPRESS_DB_PASSWORD and MYSQL_ROOT_PASSWORD.

Now after you have set these following variables you will have to run the containers with the help of docker-compose:

$ docker-compose up -d

In this scenario you will have to take one more view into the Traefik admin dashboard, viewing which you get a backend and a frontend for the two revealed servers:

Image Source: https://do.co/2PxbSau

Guide to blog.your_domain, by exchanging your_domain with your domain. You will be then redirected to a TLS connection and now you can complete the setup for WordPress:

Image Source: https://do.co/2QmRoXn

You will now have to access Adminer by going to db-admin.your_domain in your browser, and then again replacing  your_domain with your domain. The adminer container has access to the mysql container through the internal Docker network, however it is not revealed to the outside world, but the adminer container has access to it that they share using the mysql container name as a host name.

You will have to use username root on the Adminer login screen, for the server use  mysql, and you will have to use the value you set for MYSQL_ROOT_PASSWORD for the password. After you are logged in, you will find the Adminer user interface:

Image Source: https://do.co/2BdpO4y

You will find that both the sides are now working and you will be able to use the dashboard at monitor.your_domain so that you can keep a watch over your applications.

Conclusion

Therefore from this blog you got to know how you will configure Traefik in order to proxy requests to the other applications in the Docker containers. There is no need to restart the traefik container when you add new applications to proxy traffic to since Traefik notices the changes immediately through the Docker socket file it’s monitoring Traefik’s declarative configuration at the application container level makes it easy to configure more services.

Header Image Source: https://bit.ly/2RP1ddh

mm

Barry Davis is a Technology Evangelist who is joined to Webskitters for more than 5 years. A specialist in Website design, development & planning online business strategy. He is passionate about implementing new web technologies that makes websites perform better.

Facebooktwittergoogle_pluspinterestlinkedin

Interested in working with us?

We'd love to hear from you
Webskitters LLC
7950 NW 53rd St #337 Miami, Florida 33166
Phone: 732.218.7686