Mastering Traefik v3: Automated Docker Reverse Proxy & Let's Encrypt SSL Configuration
Introduction to Modern Ingress Management with Traefik v3
In the era of microservices and containerization, managing network traffic efficiently is a foundational requirement for any robust infrastructure. Traditional reverse proxies often require manual configuration updates and service restarts whenever a new container is deployed. Traefik v3 revolutionizes this workflow by acting as an cloud-native, edge router that integrates natively with Docker.
Unlike legacy systems, Traefik constantly listens to the Docker daemon provider API. When a container is spun up or torn down, Traefik dynamically updates its routing rules in real-time without any downtime or manual intervention. Combined with built-in, automated ACME TLS certificate management via Let's Encrypt, Traefik v3 provides an elegant, hands-off solution for securing and routing your containerized business applications. This guide walks you through setting up a production-ready Traefik v3 architecture from scratch.
Core Concepts: EntryPoints, Routers, Middlewares, and Services
Before diving into configuration files, it is vital to understand the foundational architecture of Traefik v3. Traefik processes requests using a clearly defined, modular pipeline:
- EntryPoints: These define the network ports that Traefik listens on (e.g., port 80 for HTTP and port 443 for HTTPS).
- Routers: Routers analyze incoming requests reaching an EntryPoint and determine if they match specific rules, such as hostnames (
Host(`app.example.com`)) or path prefixes. - Middlewares: Components that can tweak a request or response before or after it reaches the backend. Examples include security headers, basic authentication, or automatic HTTP-to-HTTPS redirection.
- Services: These configure how to reach the actual backend containers that will handle the incoming requests. Traefik automatically manages load balancing across multiple replicas of a service.
Note: Traefik v3 introduces significant performance improvements, native support for HTTP/3, and updated syntax for routing definitions compared to older v2 deployments.
Step 1: Setting Up the Directory Structure and Network
To ensure a clean deployment, create a dedicated directory structure on your host machine. This separation keeps configuration files isolated and persistent storage well-defined.
mkdir -p /opt/traefik/data
touch /opt/traefik/data/traefik.yml
touch /opt/traefik/data/acme.json
chmod 600 /opt/traefik/data/acme.jsonCRITICAL SECURITY NOTE: The acme.json file will store your private SSL keys generated by Let's Encrypt. Docker will refuse to use it, or Let's Encrypt validation will fail, if the file permissions are too open. Setting it to chmod 600 ensures that only the file owner can read and write to it.
Next, create a dedicated Docker network. This allows Traefik to communicate securely with other containers while isolating them from the public host network interface.
docker network create traefik-publicStep 2: Crafting the Static Configuration (traefik.yml)
The static configuration defines the core settings of Traefik that do not change frequently, such as entrypoints, provider APIs, and SSL certificate providers. Save the following content into /opt/traefik/data/traefik.yml:
api:
dashboard: true
insecure: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
providers:
docker:
exposedByDefault: false
network: traefik-public
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /acme.json
httpChallenge:
entryPoint: webIn this setup, we have configured a seamless global HTTP-to-HTTPS redirection on the web entrypoint. Any traffic hitting port 80 is immediately upgraded to encrypted port 443. We also declared our certificate resolver using the httpChallenge validation method, which requires port 80 to be publicly accessible from the internet.
Step 3: Deploying Traefik v3 via Docker Compose
With our static configuration in place, we can now launch Traefik using Docker Compose. Create a docker-compose.yml file inside the /opt/traefik/ directory:
version: "3.8"
services:
traefik:
image: traefik:v3.0
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /opt/traefik/data/traefik.yml:/traefik.yml:ro
- /opt/traefik/data/acme.json:/acme.json
networks:
- traefik-public
labels:
- "traefik.enable=true"
# Dashboard routing configuration
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.middlewares=auth"
# Simple HTTP Basic Auth for Dashboard Security (admin:password_hash)
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$uo7rDe0a$$9R7b8Y7Fj2vW/WUkpM1X1."
networks:
traefik-public:
external: trueNote the use of /var/run/docker.sock:/var/run/docker.sock:ro. Mounting the Docker socket as read-only (ro) is an essential security practice that limits Traefik's permissions, preventing malicious internal actors from manipulating the host machine's Docker daemon maliciously.
Step 4: Verifying Automated Container Discovery
Now, let's deploy a business application container to see automated discovery and SSL configuration in action. We will spin up a lightweight Nginx web application. Notice that this container does not need ports exposed directly to the host machine; everything routes internally via the traefik-public network.
version: "3.8"
services:
webapp:
image: nginx:alpine
container_name: demo-web-app
restart: always
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.webapp.entrypoints=websecure"
- "traefik.http.services.webapp.loadbalancer.server.port=80"
networks:
traefik-public:
external: trueOnce you execute docker compose up -d on this stack, Traefik immediately catches the lifecycle event emitted by Docker. It reviews the labels, constructs a routing rule for app.example.com, signals Let's Encrypt to complete the HTTP challenge, provisions an SSL certificate, and initiates secure routing—all within seconds.
Best Practices for Production Environments
To ensure a resilient engineering deployment, always keep the following production-grade practices in mind:
- Log Management: Configure proper access logging and error logging parameters within
traefik.ymlto export logs to structured JSON files, easing parsing via ELK or Grafana Loki stacks. - Rate Limiting: Protect your upstream application services against DDoS vectors or brute-force requests by enabling Traefik's native RateLimit middleware.
- Strict Security Headers: Use a customized headers middleware to enforce HTTP Strict Transport Security (HSTS), X-Frame-Options, and X-Content-Type-Options across all routed microservices.
Conclusion
Traefik v3 provides modern engineering teams with a dynamic, self-healing, and maintenance-free approach to traffic management. By replacing tedious manual configuration scripts with explicit, infrastructure-as-code Docker labels, systems engineers save hours of manual onboarding time. Implementing automatic dynamic discovery and seamless automated SSL certificates allows you to focus on developing functionality rather than maintaining infrastructure plumbing.
