1. home
  2. posts
  3. about
  4. rss

Traefik HTTP router for Docker

Table of Contents


traefik-web-interface.png

Figure 1: Traefik web interface

Introduction

Traefik is an open-source Edge Router 1. It can act as a HTTP router as well as a proxy for TCP and UDP services. In many ways, it is equivalent to Nginx; however, Traefik is more easy to integrate with container back-ends such as Docker.

Traefik is a rather young project squarely aimed at those running their applications in orchestrated containers. It’s a load balancer that goes hand in hand with service discovery methods and tools, reload-less reconfiguration, modern metrics and monitoring, all the goodies that are essential when behind a nice frontend may hide hundreds of small (should I say micro?) services. 2

In this post I show how one might integrate Traefik with Docker. I also provide a default configuration file that integrates with Cloudflare and Lets Encrypt.


Setting up Traefik inside a Docker container

The following configuration was taken from a swarm environment. The Traefik container must be connected to an overlay network - here it is called traefik_public. Containers that wish to expose their services to Traefik must connect to this network.

version: "3.9"

networks:
  traefik_public:
    name: "traefik_public"
    driver: "overlay"

services:
  traefik:
    image: "traefik:latest"
    networks:
      - "traefik_public"
    ports:
      - target: 443
        published: 443
        protocol: "tcp"
        mode: "host"
    volumes:
      - "/home/ingress/mount:/etc/traefik"
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      - "CLOUDFLARE_EMAIL=<your email address>"
      - "CLOUDFLARE_API_KEY=<your api key>"
    deploy:
      mode: "replicated"
      restart_policy:
        condition: "on-failure"
      placement:
        constraints:
          - "node.hostname==<web server hostname>"

I have made the following assumptions:

  1. You are using Docker swarm
  2. You are using Cloudflare and have already created an API key
  3. The container will mount /home/ingress/mount on the host
  4. Traefik will listen on 443/tls ONLY - not 80. You can setup HTTP -> HTTPS redirects with Cloudflare

Exposing a container

Exposing a service is as simple as assigning labels to a container. Create a compose file with a labels section and add traefik.* key=value pairs.

networks:
  traefik_public:
    external: true

...

networks:
  - "traefik_public"
deploy:
  mode: "replicated"
  labels:
    # traefik
    - "traefik.enable=true"
    - "traefik.docker.network=traefik_public"
    # http (your-domain.net)
    - "traefik.http.routers.wordpress.entrypoints=websecure"
    - "traefik.http.routers.wordpress.rule=Host(`your-domain.net`)"
    - "traefik.http.routers.wordpress.tls.certresolver=letsencrypt"
    - "traefik.http.routers.wordpress.service=wordpress"
    - "traefik.http.services.wordpress.loadbalancer.server.port=80"
  restart_policy:
    condition: "on-failure"
  placement:
    constraints:
      - "node.hostname==<web server hostname>"

The above configuration assumes a service called wordpress. Traefik will request a TLS certificate from Lets Encrypt and will forward requests to the local service "wordpress" listening on port 80. Please see 3 for a full list of available labels and configuration options.


A sensible configuration file

Traefik revolves around a central configuration file. You should create yours under /home/ingress/mount/traefik.toml and add the following.

[global]
  checkNewVersion = true
  sendAnonymousUsage = false

[log]
  level = "INFO"

[api]
  dashboard = true

[accessLog]
  bufferingSize = 1024
  filePath = "/etc/traefik/access-log.json"
  format = "json"
  [accessLog.fields]
    defaultMode = "drop"
    [accessLog.fields.names]
      "Duration" = "keep"
      "ClientHost" = "keep"
      "ClientPort" = "keep"
      "RequestHost" = "keep"
      "RequestPath" = "keep"
      "RequestMethod" = "keep"
      "RequestProtocol" = "keep"
      "RequestScheme" = "keep"
      "RouterName" = "keep"

[metrics]
  [metrics.prometheus]
    entryPoint = "websecure"
    manualRouting = true

[entryPoints]
  [entryPoints.websecure]
    address = ":443/tcp"
    [entryPoint.websecure.forwardHeaders]
      trustedIPs = ["127.0.0.0/32", "172.0.0.0/8"]

[certificatesResolvers.letsencrypt.acme]
  email = "your email address"
  storage = "/etc/traefik/acme.json"
  [certificatesResolvers.letsencrypt.acme.dnsChallenge]
    provider = "cloudflare"
    delayBeforeCheck = 0

[providers]
  [providers.file]
    directory = "/etc/traefik/conf"
    watch = true
  [providers.docker]
    endpoint = "unix:///var/run/docker.sock"
    swarmMode = true
    exposedByDefault = false
    watch = true

This will enable the web dashboard and set the log level to INFO. An access log will be kept under /home/ingress/mount/access-log.json - high traffic sites should not keep an access log like this as it will grow very quickly. Prometheus metrics will also be exposed so metrics can be scraped and loaded into e.e. Grafana. Two back-ends are defined: one for Docker and one for static files under /home/ingress/mount/config.


Configuring the web dashboard

Traefik provides a web dashboard for monitoring and visualising the system status. To enable the dashboard, create the configuration file /home/ingress/mount/conf/admin.toml and add the following.

[http.middlewares]
  [http.middlewares.traefik-admin.basicAuth]
    users = [
      "username:hash"
    ]

[http.routers.traefik-metrics]
  entrypoints = ["websecure"]
  rule = "(Host(`traefik.your-domain.net`) && Path(`/metrics`))"
  service = "prometheus@internal"
  middlewares = ["traefik-admin"]
  [http.routers.traefik-metrics.tls]
    certresolver = "letsencrypt"

[http.routers.traefik-dashboard]
  entrypoints = ["websecure"]
  rule = "Host(`traefik.your-domain.net`)"
  service = "api@internal"
  middlewares = ["traefik-admin"]
  [http.routers.traefik-dashboard.tls]
    certresolver = "letsencrypt"

The dashboard will be accessible on https://traefik.your-domain.net, and Prometheus metric can be scraped from https://traefik.your-domain.net/metrics.

Note: both routes are protected by the basic auth middleware defined under http.middlewares.traefik-admin.basicAuth]. You must provide a username and password in "basic auth" format. You can use this online tool or create the string manually.


Footnotes:

Last updated: Monday 19 February, 2024