Post

Master Traefik v3: Easy Docker Reverse Proxy Setup with Cloudflare SSL

Master Traefik v3: Easy Docker Reverse Proxy Setup with Cloudflare SSL

Traefik has become the defacto standard for routing traffic in Docker environments. Its ability to automatically discover services and handle SSL certificates effortlessly makes it a favorite among DevOps engineers and homelab enthusiasts a like.

In this guide, we will set up Traefik v3 using Docker Compose. We’ll configure it to automatically provision Let’s Encrypt SSL certificates using the Cloudflare DNS Challenge, ensuring your internal and external services are secure by default.

Prerequisites

Before we start, ensure you have the following:

  • Docker & Docker Compose installed on your server.
  • A Domain Name managed by Cloudflare.
  • A Cloudflare API Token with Zone:DNS:Edit permissions.

Directory Structure

Organization is key. We’ll keep our main compose file in the root and our static configuration in a config subdirectory.

1
2
3
4
5
.
├── config/
│   └── traefik.yaml  # Static configuration
├── docker-compose.yaml
└── .env              # Secrets (API Tokens)

Step 1: The Static Configuration (traefik.yaml)

The traefik.yaml file controls the startup behavior of Traefik. Here, we define our entry points (ports 80 and 443), enable the dashboard, and configure the Cloudflare certificate resolver.

Create config/traefik.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
 level: DEBUG  # Set to INFO or ERROR for production

api:
  dashboard: true
  insecure: true  # ⚠️ Only for setup/debugging. Secure this in production!

entryPoints:
  web:
    address: :80
    # Automatically redirect HTTP to HTTPS
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: :443

certificatesResolvers:
  cloudflare:
    acme:
      storage: /var/traefik/certs/cloudflare-acme.json
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

providers:
  docker:
    exposedByDefault: false  # Explicitly enable Traefik on specific containers
    network: frontend        # The Docker network to watch
  file:
    directory: /etc/traefik
    watch: true

Note⚠️: We’ve set api.insecure: true to easily access the dashboard on port 8080. In a production environment, you should disable this and route the dashboard through a secure router with basic auth middleware.

Step 2: The Docker Compose File

Now, let’s define the Traefik service. We need to map the necessary ports, mount volumes for configuration and certificates, and pass our Cloudflare credentials.

Create docker-compose.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
services:
  traefik:
    image: docker.io/library/traefik:v3.6.4
    container_name: Traefik
    ports:
      - 80:80
      - 443:443
      - 8080:8080    # Traefik Dashboard
    volumes:
      - /run/docker.sock:/run/docker.sock:ro   # Allow Traefik to listen to Docker events
      - ./config/:/etc/traefik/:ro             # Mount our static config
      - /home/ubuntu/docker/traefik/certs/:/var/traefik/certs/:rw # Persistent storage for certs
    env_file:
      - .env
    networks:
      - frontend
    restart: unless-stopped

networks:
  frontend:
    external: true

Tip💡: Ensure the frontend network exists before starting. Run docker network create frontend if you haven’t already. This allows other containers to talk to Traefik.

Step 3: Managing Secrets with .env

Never hardcode your API tokens in docker-compose.yaml. Instead, create a .env file in the same directory:

1
2
CF_DNS_API_TOKEN=your_cloudflare_api_token_here
CF_API_EMAIL=[email protected]

Traefik will use these environment variables to authenticate with Cloudflare during the SSL challenge.

Step 4: Deployment

With everything in place, deploy the stack:

1
docker compose up -d

Check the logs to ensure everything started correctly:

1
docker compose logs -f traefik

You should see logs indicating that the configuration was loaded successfully. If you access http://<your-server-ip>:8080, you will see the Traefik dashboard!

Summary

You now have a robust reverse proxy capable of automatically issuing wildcard SSL certificates via Cloudflare. Any new Docker container added to the frontend network with the correct labels will be automatically routed and secured.

This post is licensed under CC BY 4.0 by the author.