traefik

I have come to appreciate Traefik as a reverse proxy. I now run several Traefik instances. Traefik is highly configurable and has reliably renewed my SSL certificates for years.

Traefik can be configured in several ways. For example, it supports using labels from Docker containers. You can configure routes through labels directly in a docker-compose.yml file. Traefik then picks up the route, provided the containers are on the same network.

At home, I run Traefik with Docker in an LXC container. The LXC container has a static IP on my server network. In this environment, I prefer a fixed configuration using files.

Configuration

I use INWX as my domain provider. To make wildcard certificates work, I added the following variables to the referenced traefik.env file:

INWX_USERNAME=xxxxxxxxxxx
INWX_PASSWORD=xxxxxxxxxxx
INWX_SHARED_SECRET=xxxxxxxxxxx

If you also use INWX, simply replace the masked values with your own.

The provider configuration is also worth noting. I configured it so I can add more configuration files, which Traefik loads from a subdirectory.
The watch: true setting makes Traefik detect file changes and load them immediately. This means I do not need to restart the Traefik server whenever I make a change.

Here is my base configuration:

api:
  insecure: true
  dashboard: true
  debug: true

certificatesResolvers:
  letsencrypt:
    acme:
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      email: "christian@muench-worms.de"
      storage: "/letsencrypt/acme.json"
      httpChallenge:
        entrypoint: "http"
      dnsChallenge:
        provider: "inwx"

log:
  level: "INFO"

metrics:
  prometheus:
    entryPoint: "traefik"

providers:
  file:
    directory: "/etc/traefik/configurations"
    watch: true

ping:
  entryPoint: "http"

My configuration subdirectory contains these files:

  • middlewares.yml
  • router.yml
  • services.yml
  • tcp.yml
  • tls.yml

I split routes, middlewares, and services into separate files.
A request is generally processed in the following order:

Entrypoint -> Router -> Middleware -> Service

Router

http:

  # ----------------------------------
  # Router
  # ----------------------------------

  routers:

    # ----------------------------------
    # Routes: muench.dev
    # ----------------------------------

    archivebox:
      rule: "Host(`archivebox.muench.dev`)"
      entryPoints:
        - http
        - https
      middlewares:
        - https_redirect
      service: archivebox
      tls:
        certResolver: letsencrypt
        
    # .... additional routes

Middleware

http:
  # ----------------------------------
  # Middlewares
  # ----------------------------------

  middlewares:
  
    https_redirect:
      redirectscheme:
         scheme: https
         permanent: true
         
   # .... additional middlewares

Services

Here is an example service configuration:

http:
  # ----------------------------------
  # Services
  # ----------------------------------
  services:

    archivebox:
      loadBalancer:
        servers:
          - url: "http://archivebox.muench.lan"
          
    # .... additional services

Docker Compose

This is my docker-compose.yml file

services:
  traefik:
    container_name: traefik
    
    # Use a newer Traefik version here if needed
    image: traefik:3.3.1
    
    restart: always
    env_file:
      - traefik.env
    ports:
      # The HTTP ports
      - "80:80"
      - "443:443"
      # The Web UI (enabled by --api)
      - "8080:8080"
      # Home Assistant
      - "8123:8123"
      # imaps
      - "993:993"
      # git ssh
      - "22222:22222"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      #- "/var/log/crowdsec/traefik/:/var/log/traefik/"
      - "./volumes/letsencrypt:/letsencrypt"
      - "./etc:/etc/traefik"
      - "./volumes/certs:/certs"
    cap_add:
      - NET_ADMIN