# Traefik


# 1. Prerequisites

Before we begin, create a directory for your Docker data (if you haven't already), then create a directory for Traefik:

mkdir docker_volumes
cd docker_volumes

mkdir traefik
cd traefik

By the end of this guide, your directory structure should look something like this:

./traefik
├── cf_api_token.txt
├── data
│   ├── acme.json
│   └── traefik.yml
└── docker-compose.yaml

# 2. Configuring Docker Compose

Create a docker-compose.yaml file inside the traefik directory:

touch docker-compose.yaml
nano docker-compose.yaml

Then add the following content to the docker-compose.yml file:

docker-compose.yaml
services:
  traefik:
    image: traefik
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges: true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    environment:
      CF_DNS_API_TOKEN_FILE: /run/secrets/cf_api_token
      TRAEFIK_DASHBOARD_CREDENTIALS: ${TRAEFIK_DASHBOARD_CREDENTIALS}
    secrets:
      - cf_api_token
    env_file: .env
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASHBOARD_CREDENTIALS}"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
      - "traefik.http.routers.traefik-secure.tls.domains[0].main=example.com"
      - "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.example.com"
      - "traefik.http.routers.traefik-secure.service=api@internal"

secrets:
  cf_api_token:
    file: ./cf_api_token.txt

networks:
  proxy:
    external: true

# 3. Set up the Data Directory

After creating and configuring your docker-compose.yml file, create and navigate to the data directory. Inside the data directory, create the acme.json file to store the Let's Encrypt certificates. Then, set the appropriate permissions (read/write for owner, no access for others):

mkdir data 
cd data
touch acme.json
chmod 600 acme.json

In the data directory, create the traefik.yml configuration file:

nano traefik.yml

Then, add the following content to the traefik.yml file:

traefik.yml
api:
  dashboard: true
  debug: true
entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"
serversTransport:
  insecureSkipVerify: true
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
certificatesResolvers:
  cloudflare:
    acme:
      email: [email protected]
      storage: acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

After configuring traefik.yml, create a Docker network for Traefik:

docker network create proxy

Finally, create a file to store your Cloudflare API Token secret:

touch cf_api_token.txt
nano cf_api_token.txt

# 4. Traefik Dashboard Authentication

To secure access to the Traefik dashboard, generate a bcrypt-hashed password using htpasswd. You can install it by running:

apt install apache2-utils

Then, use the following command to generate a bcrypt-hashed password:

echo $(htpasswd -nB exampleUser) | sed -e s/\\$/\\$\\$/g
New password: [REDACTED]
Re-type new password: [REDACTED]
exampleUser:$$2y$$05$$.UQL...RlW

Next, create an .env file:

touch .env
nano .env

Finally, add the following credentials to the .env file:

TRAEFIK_DASHBOARD_CREDENTIALS=exampleUser:$2y$05$abc...xyz

# 5. Start Traefik

With everything set up, (re)start the Docker container to apply changes:

docker compose up -d --force-recreate

Congratulations! You’ve just set up Traefik! However, if you head over to the website specified in your Docker Compose file, it won’t resolve since you're missing a local DNS entry. To fix this, you’ll need a DNS system that can resolve local DNS records. You can either configure your router (if it supports local DNS records) or use Pi-hole. Pi-hole is a DNS sinkhole that also offers network-wide ad blocking, but I primarily use it for managing local DNS domains.

For a guide on setting up Pi-hole, check out my guide here. WIP


# 6. Troubleshooting

WIP