Traefik is an awesome open-source tool from Containous which makes reverse proxying traffic to multiple apps easy. It runs in a Docker container, which means setup is fairly simple, and can handle routing to multiple servers from multiple sources.

We use Traefik to power some of our edge SSL solution here at Qloaked, but if you’re trying to figure out how to set up a secure reverse proxy and you DON’T want to use Qloaked, here’s a simple guide to get you started.

Getting Traefik Running with Docker

You’ll need to install Docker before you go any further, as Traefik won’t work without it. Get the image from here.

Create a new directory to hold your Traefik config:

mkdir traefik-server
cd traefik-server

Then, create a single file (yes, just one!) in it to hold our Docker config:

touch docker-compose.yml

In your new docker-compose.yml file, enter the boilerplate config and save it:

version: '3'

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:v2.2
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock

Start your reverse proxy service:

docker-compose up -d reverse-proxy

With that command, Docker should pull the Traefik library and run it in a container. To confirm that it’s created and running, enter:

docker ps

You should see a list of all containers and the process status (I’ve hidden the non-relevant ones):

To confirm that the proxy is working as expected, visit http://localhost:8080/api/rawdata to see the config.

Setting up a simple endpoint

Now, we’ll define the service which we want to proxy traffic to. At Qloaked we call this the application endpoint (and it’s not a local Docker server), but for this instance we’ll use the basic whoami Docker service provided for us by Containous.

Add the details of the new service at the bottom of your docker.compose.yml. It should be the next entry in the services list (after the ‘reverse-proxy’ service):

  whoami:
      # A container that exposes an API to show its IP address
      image: containous/whoami
      labels:
        - traefik.http.routers.whoami.rule=Host('http://whoami.docker.localhost/') #sets the rule for the router

Start the service like we did previously:

docker-compose up -d whoami

Run docker ps to make sure it’s started, or visit http://localhost:8080/api/rawdata and see the new entry in the for yourself.

You can also visit the page for yourself, by heading to http://whoami.docker.localhost/ in your browser.

Setting up Traefik with Lets Encrypt

Now that we’ve got the proxy and the endpoint working, we’re going to secure the traffic.

We’ll need to create a new static config file to hold further information on our SSL setup. Do that by adding a traefik.yml in your working directory (it can also be in /etc/traefik/, $XDG_CONFIG_HOME/, or $HOME/.config/):

touch traefik.yml

Now, enter defined entry points and the specified certificate resolver (in this case, Let’s Encrypt):

entryPoints:
  web:
    address: ":80"

  websecure:
    address: ":443"

certificatesResolvers:
  letsEncrypt:
    acme:
      email: you@example.com
      storage: /etc/traefik/acme/acme.json
      httpChallenge:
        # used during the challenge
        entryPoint: web

You’ll need to enter your own email address in the email section.

With that in place, we can go back to our docker-compose.yml file and add some specific config to request Let’s Encrypt security on our whoami service.

Note that per the Traefik documentation, you must specify that a service requires the certificate resolver – it doesn’t automatically get used. 

Update the configuration labels as follows:

  whoami:
      # A container that exposes an API to show its IP address
      image: containous/whoami
      labels:
        - traefik.http.routers.whoami.rule=Host('yourdomain.org') #sets the rule for the router
        - traefik.http.routers.whoami.tls=true #sets the service to use TLS
        - traefik.http.routers.whoami.tls.certresolver=letsEncrypt #references our certificatesResolvers in traefik.yml
        - traefik.http.routers.whoami.tls.domains[0].main=yourdomain.org #optionally restrict domain

Adding tls.domains is optional (per the Traefik docs) – if it’s not set, the certificate resolvers will fall back to using the provided routers rule and attempt to provision the domain listed there.

With this simple configuration in place, we have a working setup where Traefik, Let’s Encrypt and Docker are working together to secure inbound traffic. Magic!

Of course, if you’re not into a roll-your-own solution, you could use Qloaked’s pre-configured SSL at the edge services.

Comments are closed.