Setting Up Traefik 2 with Local SSL Certificate

Posted March 11th, 2020

I recently updated our local Docker development stacks to use Traefik version 2. Traefik is an edge router application that makes setting up services and routes rather simple.

I found the process of enforcing HTTPS traffic a bit challenging and required a lot more effort than version 1 of Traefik. All of our projects use HTTPS only with a self signed certificate for local development, no HTTP. Hopefully sharing this information helps some folks out.

First, in your docker-compose.yml file, we need to update the Traefik service to use 2.0, and new commands:

  traefik:
    image: traefik:v2.0
    container_name: "${PROJECT_NAME}_traefik"
    command:
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker=true
      - --providers.file.directory=/etc/traefik/dynamic_conf
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - ./tools/certs:/tools/certs
      - ./tools/traefik/config.yml:/etc/traefik/dynamic_conf/conf.yml:ro
      - /var/run/docker.sock:/var/run/docker.sock

The command section provides the container with runtime configuration overrides. Here, we are defining two named entry points on port 80 and 443. We also tell it that Docker is the provider, and to look in a directory in the container for provider configuration.

Second, we expose ports 80 and 443. Nothing new there.

In the volumes section, I am mounting a directory in the root of my project into the container. This directory contains the local certificate for the project. Second, I mount a yaml file into the container, located in the directory we configured to be the provider directory from the command section.

Now, create the config.yml file. It contains the location of the certificate and key for Traefik:

tls:
  certificates:
    - certFile: /tools/certs/cert.crt
      keyFile: /tools/certs/cert.key

These paths exist in the container, as defined by the volumes section.

Now, we need to configure the Apache container for Traefik and define a middleware, and tell Traefik how to route the traffic:

  apache:
    ...other config truncated...
    labels:
      - traefik.http.middlewares.${PROJECT_NAME}_apache_https.redirectscheme.scheme=https
      - traefik.http.routers.${PROJECT_NAME}_apache.entrypoints=web
      - traefik.http.routers.${PROJECT_NAME}_apache.rule=Host(`${PROJECT_BASE_URL}`)
      - traefik.http.routers.${PROJECT_NAME}_apache.middlewares=${PROJECT_NAME}[email protected]
      - traefik.http.routers.${PROJECT_NAME}_apache_https.rule=Host(`${PROJECT_BASE_URL}`)
      - traefik.http.routers.${PROJECT_NAME}_apache_https.tls=true
      - traefik.http.routers.${PROJECT_NAME}_apache_https.entrypoints=websecure

The first line creates a middleware that redirects to https. The next few lines define a router with entrypoint and a rule for HTTP traffic with the project URL. We also attach our middleware to that router, which redirects all traffic to https. The remaining lines define a new router (note the slightly different router name with _https attached) and rule, with the websecure (443) entrypoint and TLS enabled. This will set that router to accept HTTPS requests only.

Now, any HTTP traffic be directed to HTTPS. You can then add your self signed certificate to your browser so it is recognized and trusted for your local development environment.