Introduction to Docker and Traefik!

Why Docker and Traefik?

Recently I decided to redeploy my home-server. It was still running Ubuntu 12.04 and the configuration drifted ever since it was setup. Time for a revamp. I opted to use Docker and Traefik because I wanted a setup that was easy to update and easy to maintain.

All the applications I use are available on hub.docker.com. Keeping all configuration in a single GIT repo using docker-compose makes it easy to maintain my infrastructure.

I also decided to introduce a reverse proxy, this allows all my applications to be available by entering a domain name (no more remembering ports!). Docker and Traefik combined make that easy. On top of that it’s also very easy to add SSL due to Traefik’s the Let’s encrypt integration.

In this blog post we will be building this using Docker and Traefik:
Docker and Traefik

What distribution to choose?

For my home-server I opted to use Alpine Linux because it’s lightweight and an excellent docker host. For this blog post I’ll be using Amazon Linux so it’s easy for you to follow along. However, you can use any other distribution that you are happy with.

Docker host and firewall rules

We will start by spinning up a new host OS, next we will setup firewall rules. Depending on what you’re using instructions might slightly differ. The instructions below are for AWS.

Start a new host-os, I’m using Amazon Linux:
aws-linux-ami

We should open the following ports in the firewall:

  • 22 (to SSH into the machine, you should trim this down to your own IP).
  • 80 (for HTTP traffic, required for requesting the SSL certificates from Let’s encrypt using the HTTP challenge).
  • 443 (for HTTPS)

firewall rules

Creating the DNS record set

We want our Docker apps to be available over the internet and we are going to setup HTTPS. Hence, we need to own a DNS domain. In order for Traefik to request certificates for the domain, we need to set up DNS first. We can either create A-Records, or use a CNAME. I will use the following two CNAME records.

  • *.dockerdemo.yourdomain – This will be used by containers (e.g. app1.dockerdemo.javydekoning.com)
  • dockerdemo.yourdomain – This will be used by Traefik (This is NOT required, we could also use traefik.dockerdemo.javydekoning.com)

From the instance/VM we just created, copy either the public IP (to be used in an A-Record), or the Public DNS name (to be used in a CNAME record). I will be using the public DNS name, therefore I’ll create a CNAME record.

Instructions will differ depending on your DNS provider. My zone is hosted in Route53, so we can create a record by clicking “Create Record Set” in the AWS console. We use a wildcard (*) record because we plan to create multiple sub-domains for our containers.

dns-settings

Route 53

Configuring the Docker host

The OS only needs to run Docker and Docker-Compose all the other applications will run in containers. Let’s set that up. We’ll install docker, docker-compose and make sure the docker daemon is started on system boot.

Next, we will create the required files and folders. That will look like this:

Create and set permissions:

Creating a Traefik container.

First we setup our Traefik container. This container will act as a reverse proxy and redirect the traffic to the correct container. For this we will have to set up two files:

  1. /dockerdemo/docker-compose.yml – This will tell docker what containers to run
  2. /dockerdemo/traefik/traefik.toml – This will hold the Traefik config

traefik.toml

We will start with the traefik config file. We want to configure the Traefik webinterface [web] and re-direct all http traffic to https to encrypt all our traffic. Finally, when we create a new docker container we don’t want to reconfigure Traefik, hence we tell Traefik to watch Docker.

Open traefik.toml in the editor of your choice and edit as follows:

docker-compose.yml

Next we will setup our docker-compose.yml file. We will start with just the Traefik container.

Some key pointers:

  1. docker.sock we map the sock file from the host container, so Traefik can monitor changes in the docker environment.
  2. ./traefik/* maps the configuration file and certificate store from our host to our Traefik container.
  3. traefik.port tells traefik to which backend port traffic needs to be redirected.
  4. traefik.frontend.rule tells traefik which ‘Host header’ should be redirected to this container.

Testing!

Make sure you are in the directory of you docker-compose.yml file and run

Now go to the IP of your container host to see if it works. You should see:
404
Don’t worry about the 404. This is what we expect! Remember, we told Traefik ONLY to redirect traffic to our container if the http host header is ‘dockerdemo.yourdomain’. Let’s test that as well, you should be redirected to HTTPS and see:

If you are presented with an invalid certificate, troubleshoot using:

Adding two more containers.

Finally we will introduce two more containers.

  1. Portainer – lightweight management UI for your docker environment.
  2. whoami – simple HTTP docker service that prints it’s container ID.

For the whoami container we will also add a form of authentication. You can skip this if you don’t want that, or you can use the hash I generated (for testing only).

We will generate a secure Bcrypt hash. On your local machine install the apache2 utils and run:

This should return:

You need to duplicate the ‘$’ in this string when adding this to your docker-compose.yml file.

Let’s complete our docker-compose.yml file:

There is one newly added label:

  1. traefik.frontend.auth.basic tells traffic to use basic authentication to authenticate a user before passing traffic on to the container.

Final Docker and Traefik test!

Make sure you are in the directory of you docker-compose.yml file again and run

This should bring up the two remaining containers. Now the first thing you should do is go to portainer.yourdomain and SET the initial credentials.

Next go to app1.yourdomain, and you should be asked for the credentials that you’ve created with the ‘htpasswd’ tool. If you’ve used my exact example that would be

  • user: username
  • pass: YouShouldNotUseThisPassword!

Now you should see this:
certificate

All done!

Congrats, you’ve configured Docker and Traefik (reverse-proxy), Docker-Compose, ssl and authentication!

Leave a Comment

Your email address will not be published. Required fields are marked *