In this post, I shared my Traefik configuration. Back then, I’d just learned about Traefik and followed a few posts to set things up and get them working with all of my containers. Since then, I’ve used Traefik for every new container I’ve set up, I’ve run servers like Minecraft and 7 Days to Die through it, as well as numerous different DevOps-adjacent containers. So whilst I’m no means an expert, I’m definitely a little more adept at some of its configuration nuances (I’ll be publishing something next week about how to globally disable TLS 1.0 and 1.1 so keep an eye out for that).
Caveats
As per normal, ensure the below are met before starting this:
- You’ve backed up your current config, certs volume, docker-compose.yml file and/or anything related to the running version of Traefik
- You’re doing this with Traefik in a Docker container
- The same principal applies to a natively running version of Traefik I suppose, just ignore the bit about passing the file through to the container
- You understand basic Docker concepts such as bringing a container up and down, and managing your configuration through a docker-compose.yml file
Static or Dynamic?
The best descriptor of the differences is probably the image above. All you really need to be concerned about is the following:
- Static runs at startup
- Dynamic runs each time a new request comes in to Traefik
Because of this distinction, there are certain elements that fit naturally into each of these categories. In the current config (located at the bottom of the post), Static options are provided via the ‘command’ key. There are certain Dynamic options that can be specified in the ’labels’ key (the normal router creation, certresolver binding, etc) but we won’t go over those in detail just yet.
Converting YAML Into… YAML?
Technically, to convert from the cmdline style flags to a permanent YAML file we’re going from docker-compose.yml
to traefik.yml
, but you’ll see that the format will wind up looking a little different. If you’ve worked with JSON at all, the way to split these up should look rather familiar. The basic gist is that everywhere you see a period, you insert a new line.
As an example, the command argument
- --entrypoints.http.address=:80
will translate into
entryPoints:
http:
address: 80
Create a file called traefik.yml
in the same directory as your docker-compose.yml
file (or don’t, I’m not your dad… Just don’t forget to amend the final volume mapping below) and convert these lines into sweet, sweet YAML. Once you’ve completed the whole ‘command’ key, you should have a file like the below (certain config will accept either true
or {}
as valid to turn them on, always worth double checking the docs for which is preferred):
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker: {}
certificatesResolvers:
le:
acme:
email: name@email.tld
storage: /letsencrypt/acme.json
tlsChallenge: {}
That Rug Really Tied The Room Together
Now you have a static file on the host system, viola. Remove the ‘command’ key, rebuild the container and you’re ready to go!
What’s that? Your container is giving you an error that it can’t find the file you just created? Ahhh… We probably should have actually utilised that new file somehow, huh?
Well then, ignoring that small blunder, just add a line to your volume mappings to make the file visible inside the container (/etc/traefik/traefik
is the default location that Traefik will look for config). This is where you change the left hand side of the mapping if you located your traefik.yml
file elsewhere…
- "./traefik.yml:/etc/traefik/traefik.yml"
and you’re off to the races! Just bring the container down (you are storing your certs in a separate volume, riiiiiiight?) and back up again and Traefik will now reload, giving you this nifty little confirmation:
Now, if you ever want to add configuration to the Static options for Traefik, you just have to add them to this file and restart the container. The documentation is always a little bit more helpful when using YAML, as all things aren’t necessarily formatted for cmdline on the website.
Previous Traefik Config
version: "3.3"
services:
traefik:
container_name: traefik
image: traefik:v2.4.8
command:
# - --log.level=DEBUG
# Entrypoints
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
# Provider Info
- --providers.docker
# Certificate Resolver Info
- --certificatesresolvers.le.acme.email=name@email.tld
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.tlschallenge=true
labels:
- "traefik.enable=true"
### Middleware Redirect
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
### Global HTTP -> HTTPS Redirect
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=http"
- "traefik.http.routers.redirs.middlewares=https-redirect"
- "traefik.http.routers.redirs.priority=1"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "certs:/letsencrypt"
restart: unless-stopped
networks:
- proxy
volumes:
certs:
networks:
proxy:
driver: bridge
New Traefik Config
version: "3.3"
services:
traefik:
container_name: traefik
image: traefik:v2.4.8
labels:
- "traefik.enable=true"
### Middleware Redirect
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
### Global HTTP -> HTTPS Redirect
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=http"
- "traefik.http.routers.redirs.middlewares=https-redirect"
- "traefik.http.routers.redirs.priority=1"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "certs:/letsencrypt"
- "./traefik.yml:/etc/traefik/traefik.yml"
restart: unless-stopped
networks:
- proxy
volumes:
certs:
networks:
proxy:
driver: bridge