Skip to content

Traefik

Opinionated

This guide is opinionated. If you use other conventions or folder layouts, feel free to change the commands and paths.

Create docker compose project

sudo mkdir -p /etc/docker/containers/traefik
cd /etc/docker/containers/traefik

Create docker compose file

File: /etc/docker/containers/traefik/docker-compose.yml

services:
  traefik:
    image: traefik:3.3
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443/tcp"
      - "443:443/udp"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/docker/volumes/traefik/traefik.yml:/traefik.yml:ro
      - /etc/docker/volumes/traefik/traefik_dynamic.yml:/traefik_dynamic.yml:ro
      - /etc/docker/volumes/traefik/acme.json:/acme.json
    networks:
      - traefik

networks:
  traefik:
    external: true

Create traefik.yml

File: /etc/docker/volumes/traefik/traefik.yml

log:
  level: INFO

entryPoints:
  web:
    address: ":80/tcp"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443/tcp"
    http:
      middlewares:
        - compress@file
        - hsts@file
      tls:
        certResolver: letsencrypt
    http3: {}

api:
  dashboard: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: $mail@example.com$
      storage: acme.json
      httpChallenge:
        entryPoint: web

providers:
  docker:
    watch: true
    network: traefik
    exposedByDefault: false
  file:
    filename: traefik_dynamic.yml

serversTransport:
  insecureSkipVerify: true

Create traefik_dynamic.yml

File: /etc/docker/volumes/traefik/traefik_dynamic.yml

http:
  middlewares:
    services:
      basicAuth:
        users:
          - "$username$:$password$"
    compress:
      compress: {}
    hsts:
      headers:
        stsSeconds: 2592000
  routers:
    api:
      rule: Host(`traefik.$example.com$`)
      entrypoints:
        - websecure
      middlewares:
        - services
      service: api@internal

tls:
  options:
    default:
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
      sniStrict: true

Create acme.json

sudo touch /etc/docker/volumes/traefik/acme.json
sudo chmod 600 /etc/docker/volumes/traefik/acme.json

Create network

sudo docker network create traefik

Start traefik

sudo docker-compose up -d

You can no access the Traefik dashboard at https://traefik.$example.com$ with the credentials you set in traefik_dynamic.yml.

Add Labels to wg-easy

To add labels to your wg-easy service, you can add the following to your docker-compose.yml file:

File: /etc/docker/containers/wg-easy/docker-compose.yml

services:
  wg-easy:
    ...
    container_name: wg-easy
    networks:
      ...
      traefik: {}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wg-easy.rule=Host(`wg-easy.$example.com$`)"
      - "traefik.http.routers.wg-easy.entrypoints=websecure"
      - "traefik.http.routers.wg-easy.service=wg-easy"
      - "traefik.http.services.wg-easy.loadbalancer.server.port=51821"
    ...

networks:
  ...
  traefik:
    external: true

Restart wg-easy

cd /etc/docker/containers/wg-easy
sudo docker-compose up -d

You can now access wg-easy at https://wg-easy.$example.com$ and start the setup.