Home

Awesome

Traefik Setup with Docker Compose

This is a reusable Traefik config for usage on a virtual server or for local development using Docker Compose.
It uses:

[!NOTE] Check out solidtime - The modern Open Source Time-Tracker at solidtime.io

Table of content

Production setup

Setting up traefik

  1. Clone repository
    git clone https://github.com/korridor/reverse-proxy-docker-traefik.git
    cd reverse-proxy-docker-traefik
    
  2. Copy default config
    cp docker-compose.prod.yml docker-compose.yml
    cp -r configs-prod configs
    echo "{}" > certificates/acme.json
    chmod 600 certificates/acme.json
    
  3. Replace domain for dashboard (reverse-proxy.somedomain.com in configs/dynamic/dashboard.yml)
    http:
      routers:
        traefik:
          rule: Host(`reverse-proxy.somedomain.com`)
          # ...
        traefik-http-redirect:
          rule: Host(`reverse-proxy.somedomain.com`)
          # ...
    
  4. Replace password for admin account (in configs/dynamic/dashboard.yml)
    http:
     # ...
     middlewares:
       dashboardauth:
         basicAuth:
           users:
             - "user1:$2y$05$/x10KYbrHtswyR8POT.ny.H4fFd1n.0.IEiYiestWzE1QFkYIEI3m"
    
    • You can use a website like this to generate the hash (use Bcrypt).
    • Or generate it with: echo $(htpasswd -nB user1)
  5. Replace email for Let's encrypt (mail@somedomain.com in configs/traefik.yml)
    certificatesResolvers:
      letsencrypt:
        acme:
          # ...
          email: mail@somedomain.com
    
  6. Start container
    docker compose up -d
    
  7. Check that Traefik is running smoothly
    docker compose logs
    

Traefik dashboard

The Traefik dashboard is now available under:

https://reverse-proxy.somedomain.com

The dashboard shows you the configured routers, services, middleware, etc.

Connect docker compose service to reverse-proxy

version: '3.8'
networks:
  frontend:
    external: true
    name: reverse-proxy-docker-traefik_routing
services:
  someservice:
    restart: always
    # ...
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=reverse-proxy-docker-traefik_routing"
      # https
      - "traefik.http.routers.someservice.rule=Host(`someservice.com`)"
      - "traefik.http.routers.someservice.tls=true"
      - "traefik.http.routers.someservice.tls.certresolver=letsencrypt"
      - "traefik.http.routers.someservice.entrypoints=websecure"
      # http (redirect to https)
      - "traefik.http.routers.someservice-http.rule=Host(`someservice.com`)"
      - "traefik.http.routers.someservice-http.entrypoints=web"
      - "traefik.http.routers.someservice-http.middlewares=redirect-to-https@file"
    networks:
     - frontend
     - ...

Password protection for service with basic auth

services:
  someservice:
    # ...
    labels:
      # ...
      - "traefik.http.routers.someservice.middlewares=someservice-auth"
      - "traefik.http.middlewares.someservice-auth.basicauth.users=user1:$2y$05$/x10KYbrHtswyR8POT.ny.H4fFd1n.0.IEiYiestWzE1QFkYIEI3m"

You can generate the escaped hash with the following command: echo $(htpasswd -nB user1) | sed -e s/\\$/\\$\\$/g If you use a website like this to generate the hash remember to escape the dollar signs ($ -> $$) and use Bcrypt.

Specifying port if service exposes multiple ports

If your service exposes multiple ports Traefik does not know which one it should use. With this line you can select one:

services:
  someservice:
    # ...
    labels:
      # ...
      - "traefik.http.services.someservice.loadbalancer.server.port=8080"

SSL configuration

Per default the SSL configuration is set so that SSL Labs gives an A rating.

If you want an A+ rating, you need to use HSTS (HTTP Strict Transport Security). The setup includes a global middleware called hsts-minimal@file that can be used to activate HSTS in a simple setting. See "Global middlewares" for more information.

Global middlewares

hsts-minimal@file

Adds the HSTS header to the HTTP response without includeSubDomains and preload. The max-age is set to one year / 31536000 seconds.

hsts-standard@file

Adds the HSTS header to the HTTP response with includeSubDomains and no preload. The max-age is set to one year / 31536000 seconds.

hsts-full@file

Adds the HSTS header to the HTTP response with includeSubDomains and preload. The max-age is set to one year / 31536000 seconds.

redirect-to-https@file

Adds a permanent redirect to HTTPS.

redirect-non-www-to-www@file

Adds a permanent redirect (HTTP 301) from non-www domains to the HTTPS www domain Examples:

redirect-www-to-non-www@file

Adds a permanent redirect (HTTP 301) from www domains to the HTTPS non-www domain Examples:

Access Logs

To enable the Traefik access logs in the production configuration, open the file traefik.yml within the config folder and uncomment the accessLog section.

# Access logs
accessLog: {}

Setup for local development

Setting up Traefik

  1. Clone repository

    git clone https://github.com/korridor/reverse-proxy-docker-traefik.git
    cd reverse-proxy-docker-traefik
    
  2. Copy default config

    ln -s docker-compose.local.yml docker-compose.yml
    ln -s configs-local configs
    

    If you want to change the configuration copy the configuration instead of creating a symlink.

    cp docker-compose.local.yml docker-compose.yml
    cp -r configs-local configs
    
  3. If you want you can change the domain of the traefik dashboard (reverse-proxy.test in configs/dynamic/dashboard.yml)

    http:
      routers:
        traefik:
          rule: Host(`reverse-proxy.test`)
          # ...
    
  4. Start container

    docker compose up -d
    
  5. Check that traefik is running smoothly

    docker compose logs
    

Traefik dashboard

The Traefik dashboard is now available under:

http://reverse-proxy.test

The dashboard shows you the configured routers, services, middlewares, etc.

Connect docker compose service to reverse-proxy

version: '3.8'
networks:
  frontend:
    external: true
    name: reverse-proxy-docker-traefik_routing
services:
  someservice:
    restart: always
    # ...
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=reverse-proxy-docker-traefik_routing"
      # http
      - "traefik.http.routers.someservice.rule=Host(`someservice.test`)"
      - "traefik.http.routers.someservice.entrypoints=web"
    networks:
     - frontend
     - ...

Enabling service to send requests to itself (with someservice.test)

services:
  someservice:
    # ...
    extra_hosts:
      - "someservice.test:10.100.100.10"

Specifying port if service exposes multiple ports

If your service exposes multiple ports Traefik does not know which one it should use. With this config line you can select one:

services:
  someservice:
    # ...
    labels:
      # ...
      - "traefik.http.services.someservice.loadbalancer.server.port=8080"

Enable SSL locally

  1. Install mkcert

For example on macOS:

brew install mkcert
brew install nss # if you use Firefox

Now install the local CA:

mkcert -install
  1. Generate certificate

Replace someservice with the domains that you are using for local development.

cd certificates
mkcert -key-file local.key.pem -cert-file local.cert.pem "*.local" "*.test" "*.someservice.test" "*.someservice.local"

Enable SSL in the docker compose file

version: '3.8'
networks:
  frontend:
    external: true
    name: reverse-proxy-docker-traefik_routing
services:
  someservice:
    restart: always
    # ...
    labels:
      - ...
      # http
      - ...
      # https
      - "traefik.http.routers.someservice-https.rule=Host(`someservice.test`)"
      - "traefik.http.routers.someservice-https.entrypoints=websecure"
      - "traefik.http.routers.someservice-https.tls=true"
    networks:
     - frontend
     - ...

FAQ

I have a IPv6-only server, what do I need to change?

GitHub currently does not support cloning a repository over IPv6. You can clone from my Codeberg mirror instead:

git clone https://codeberg.org/korridor/reverse-proxy-docker-traefik.git

Credits

I used the following resources to create this setup:

License

This configuration is licensed under the MIT License (MIT). Please see license file for more information.