Skip to content

Traefik

Docker Compose

Firstly start be creating a docker-compose.yaml file, which will be used to hold the configuration for Traefik.

Traefik Docker Compose

Below is an example docker compose file that has been used to host a variety of services within docker containers.

version: '3.9'
networks:
frontend:
external: true
backend:
external: true
services:
traefik:
container_name: traefik
image: traefik:v3.1.4
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik/:/etc/traefik/
networks:
- frontend
- backend
command:
- '--api.dashboard=true'
- '--log.level=INFO'
- '--accesslog=true'
- '--providers.docker=true'
- '--providers.docker.exposedByDefault=false'
- '--providers.docker.network=frontend'
- '--providers.docker.network=backend'
- '--entrypoints.http=true'
- '--entrypoints.http.address=:80'
- '--entrypoints.https=true'
- '--entrypoints.https.address=:443'
- '--entrypoints.https.address=:27017' # mongodb
# below is en-gb IPv4 Cloudflare IPs from https://www.cloudflare.com/en-gb/en-en/ips/
- '--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22'
- '--certificatesresolvers.myresolver.acme.email='
- '--certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme.json'
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare"
- '--certificatesresolvers.myresolverr53.acme.email='
- '--certificatesresolvers.myresolverr53.acme.storage=/etc/traefik/acme.json'
- "--certificatesresolvers.myresolverr53.acme.dnschallenge=true"
- "--certificatesresolvers.myresolverr53.acme.dnschallenge.provider=route53"
- "--metrics.prometheus=true"
# - "--metrics.add.internals"
- "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0"
- "--metrics.prometheus.addEntryPointsLabels=true"
- "--metrics.prometheus.addrouterslabels=true"
- "--metrics.prometheus.addServicesLabels=true"
- "--entryPoints.metrics.address=:8899"
- "--metrics.prometheus.entryPoint=metrics"
environment:
- "CF_DNS_API_TOKEN="
- "AWS_ACCESS_KEY_ID="
- "AWS_SECRET_ACCESS_KEY="
labels:
- traefik.enable=true
- traefik.http.routers.mydashboard.rule=Host(`traefik.<domain>`)
- traefik.http.routers.mydashboard.entrypoints=https
- traefik.http.routers.mydashboard.tls=true
- traefik.http.routers.mydashboard.tls.certresolver=myresolver
- traefik.http.routers.mydashboard.service=api@internal
- traefik.http.routers.mydashboard.middlewares=myauth
restart: unless-stopped
whoami-proxy:
image: ghcr.io/goauthentik/proxy
ports:
- 9000:9000
- 9443:9443
environment:
AUTHENTIK_HOST: https://authentik.<domain>
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN:
# Starting with 2021.9, you can optionally set this too
# when authentik_host for internal communication doesn't match the public URL
# AUTHENTIK_HOST_BROWSER: https://external-domain.tld
labels:
traefik.enable: true
traefik.port: 9000
traefik.http.routers.authentik.rule: Host(`<domain>`) && PathPrefix(`/outpost.goauthentik.io/`)
# `authentik-proxy` refers to the service name in the compose file.
traefik.http.middlewares.authentik.forwardauth.address: http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
restart: unless-stopped
whoami:
image: traefik/whoami:v1.10.3
container_name: whoami
networks:
- frontend
- backend
labels:
- traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`whoami.<domain>`)
# - traefik.http.routers.whoami.middlewares=authentik@docker
- traefik.http.services.whoami.loadbalancer.server.port=80
- traefik.http.routers.whoami.entrypoints=https
- traefik.http.routers.whoami.tls=true
- traefik.http.routers.whoami.tls.certresolver=myresolver
- traefik.http.routers.whoami.service=whoami
- traefik.http.services.whoami.loadbalancer.server.scheme=http
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare"
# - traefik.http.middlewares.mywwwredirect.redirectregex.regex=^https://www\.(.*)
# - traefik.http.middlewares.mywwwredirect.redirectregex.replacement=https://$${1}
# - traefik.http.routers.mywhoami.middlewares=mywwwredirect
restart: unless-stopped

Components

Note: all the configuration above, is done using “Labels” which are part of the documentation provided by Traefik on their official website. The labels are an alternative to using the traefik.yaml file

  • Ports : Exposes HTTP (80), HTTPS (443)
  • Volumes: Configuration storage / acccess should it be required without having to access the container directly.
  • Docker Socket for container management
  • --certificatesresolvers.myresolver.acme.storage for SSL certificate storage
  • Network custom networks that are used throughout the rest of the docker containers deployed behind traefik.
  • environment specific configuration that is defined to access relevant services, required by Traefik in order to function.
  • whoami is a “test” container that displays a variety of information, used for troubleshooting.

Creating the Networks

Before deploying, networks need to be created using the Docker CLI:

docker network create frontend docker network create backend

Traefik Configuration (traefik.yaml)

global:
checkNewVersion: false
sendAnonymousUsage: false
certificatesResolvers:
route53:
acme:
email: <email>
storage: /etc/traefik/certs/route53-acme.json
caServer: 'https://acme-v02.api.letsencrypt.org/directory'
keyType: EC256
dnsChallenge:
provider: route53
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"

Important Notes

  • ACME Configuration - Primarily for HTTPS, Traefik will communicate with Lets Encrypt to obtain, issue and renew certificates as needed.
  • email - Used for any important communications from Lets Encrypt notifications.

Preparing acme.json

Create an empty acme.json file with restricted permissions to securely store SSL certificates. Based on the above configuration this needs to be created in the ./config/traefik folder.

touch acme.json
chmod 600 acme.json

Steps above are crucial to make sure that SSL certificates are kept securely and confidential.

Deploy Traefik

With configuration completed (acme.json), and the docker networks created, deploy Traefik using Docker Compose:

docker compose up -d

Securing Services with HTTPS: Example

Deploying traefik’s whoami container, using traefik labels to enable HTTPs.

Docker Compose for Traefik Whoami container

whoami:
image: traefik/whoami:v1.10
container_name: whoami
networks:
- frontend
- backend
labels:
- traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`whoami.<domain>`)
- traefik.http.services.whoami.loadbalancer.server.port=80
- traefik.http.routers.whoami.entrypoints=https
- traefik.http.routers.whoami.tls=true
- traefik.http.routers.whoami.tls.certresolver=myresolver
- traefik.http.routers.whoami.service=whoami
- traefik.http.services.whoami.loadbalancer.server.scheme=http
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare"
restart: unless-stopped

Highlights

  • Labels: Configure routing rules, entry points, certificate resolver (SSL / TLS), Loadbalancer (Access via Traefik), DNS Challenge (endpoint / service has a valid dns record, controlled through Cloudflare)
  • Networks: Ensures that Traefik’s Whoami container has the correct network access, which allows Traefik to provide the proper routing.
  • Metrics: Metrics have now been added as of 15/12/2024, which are scraped as part of the Grafana configuration.

Deployment Steps

  1. Prepare Configuration Files: Create an empty acme.json with restrictive permissions (chmod 600 acme.json) and update the Labels on the above docker compose example as required.
  2. Deploy Traefik: Use docker compose up -d in the directoy containing the above traefik docker compose file docker-compose.yaml 3.Verify Traefik Operation: Check if the Dashboard can be accessed. Configuration has been removed from the above example, so it will need to be added according to the official documentation supplied by Traefik themselves. 4.Deploy Services: Repeat the Deployment Steps for additional services required, ensuring that the appropriate labels from Traefik are included.