My configuration for Traefik 2.0, Docker, and LetsEncrypt
Tags: reverseproxy, traefik, docker, letsencrypt
Published: 2020-02-07 17:00:08

---
title: My configuration for Traefik 2.0, Docker, and LetsEncrypt
published: true
date: 2020-01-30 08:13:00 UTC
tags: reverse-proxy,traefik,docker,letsencrypt
canonical_url: https://www.simplecto.com/traefik-2-0-docker-and-letsencrypt/
---

My guess is that if you are here then you already know what you are looking for. For the benefit of everyone else, let me give you a quick tldr;

### tldr;

This is my pristine production-quality config for deploying Traefik as my front-end proxy and TLS termination server. It is the outcome of piecing together various bits from the excellent Traefik 2.0 documentation website. In addition to starting Traefik the compose file also spins up a test image so that you can confirm that it works.

### The docker-compose, decomposed

_see what I did there? yeah..._

I use docker-compose for most off my deployments it packs in the configuration and layout nicely. Traefik allows for a full config from command line arguments which obviates the need for `traefik.toml` files. It does, however, reqire and empty `acme.json` file prior to starting up.

The command line options under `command:` for Traefik turn on the api endpoint, enable the Docker provider, configure LetsEncrypt, and open listening ports on 80 (HTTP) and 443 (HTTPS).

The docker `labels`: tell Traefik to redirect all HTTP to HTTPS

You will also notice the `whoami:` container. The labels there tell Traefik to route all HTTPS traffic to `<YOUR_DOMAIN_NAME>` to that container, as well as to manage a TLS LetsEncrypt certificate.

<!--kg-card-begin: markdown-->
### docker-compose.yml

```
version: '3'

services:

    traefik:
        container_name: traefik
        image: traefik:v2.0
        command:
            - "--api.insecure=true"
            - "--providers.docker=true"
            - "--entryPoints.web.address=:80"
            - "--entryPoints.websecure.address=:443"
            - "--certificatesResolvers.le.acme.email=<YOUR_EMAIL>"
            - "--certificatesResolvers.le.acme.storage=acme.json"
            - "--certificatesResolvers.le.acme.tlsChallenge=true"
            - "--certificatesResolvers.le.acme.httpChallenge=true"
            - "--certificatesResolvers.le.acme.httpChallenge.entryPoint=web"
        restart: always
        ports:
            - 80:80
            - 443:443
            - 8080:8080
        networks:
            - web
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
            - ./acme.json:/acme.json
        labels:

            # Redirect all HTTP to HTTPS permanently
            - traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)
            - traefik.http.routers.http_catchall.entrypoints=web
            - traefik.http.routers.http_catchall.middlewares=https_redirect
            - traefik.http.middlewares.https_redirect.redirectscheme.scheme=https
            - traefik.http.middlewares.https_redirect.redirectscheme.permanent=true

    whoami:
        image: "containous/whoami"
        container_name: "simple-service"
        restart: always
        networks:
            - web
        labels:
          - traefik.http.routers.whoami.rule=Host(`<YOUR_DOMAIN_NAME>`)
          - traefik.http.routers.whoami.tls=true
          - traefik.http.routers.whoami.tls.certresolver=le

networks:
    web:
        external: true

```
<!--kg-card-end: markdown-->
### Things to note

Take note of an external `network` named `web`. This is an explicit convention I adopted so that I know only web traffic passes over it. This is the network over which Traefik communicates with other containers.

### References

- The above code is published as a gist here: [https://gist.github.com/undernewmanagement/414ce52ae4bd020115e849eaef7c54dd](https://gist.github.com/undernewmanagement/414ce52ae4bd020115e849eaef7c54dd)
- Traefik Website: [trefik.io](https://traefik.io)
- LetsEncrypt: [letsencrypt.org](https://letsencrypt.org)