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:Editpermissions.
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: trueto easily access the dashboard on port8080. 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
frontendnetwork exists before starting. Rundocker network create frontendif 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.
