Automating TLS with Traefik: Solving the Certificate Renewal Headache
Stop manually renewing SSL certificates. Learn how to use Traefik's ACME integration to automate TLS issuance and renewal using HTTP-01 and DNS-01 challenges.
20 Sept 2025, 00:59 UTC

The Manual Certificate Struggle
Managing SSL/TLS certificates manually often leads to a predictable failure: a forgotten expiration date, a panicked midnight alert, and a site that displays a "Your connection is not private" warning to every visitor. While tools like Certbot can automate this, they often require separate cron jobs and manual restarts of the web server to pick up new certificates.
The goal is to move from manual certificate management to automated lifecycle management, where the edge proxy handles the request, validation, and renewal of certificates without human intervention or service downtime.
Traefik's Approach to ACME
Traefik integrates the ACME (Automatic Certificate Management Environment) protocol directly into its core. Instead of acting as a sidecar to your application, Traefik serves as the ACME client. When a request arrives for a domain that doesn't have a valid certificate, Traefik triggers a challenge to prove domain ownership to the Certificate Authority (CA), such as Let's Encrypt.
Configuration is split into two distinct areas:
- Static Configuration: Defined at startup (via
traefik.ymlor CLI flags). This is where you define thecertificatesResolvers—the rules for how Traefik should talk to the CA. - Dynamic Configuration: Defined at runtime (via Docker labels, Kubernetes Ingress, or file providers). This is where you tell a specific router to use a particular resolver.
Choosing Your Validation Challenge
To issue a certificate, the CA must verify you control the domain. Traefik supports three primary methods, each with different engineering trade-offs:
| Method | Requirement | Best Use Case | Limitation |
|---|---|---|---|
| HTTP-01 | Port 80 open to internet | Standard web apps | Cannot issue wildcard certs |
| TLS-ALPN-01 | Port 443 open to internet | Strict security environments | Requires specific network paths |
| DNS-01 | API access to DNS provider | Wildcard certs (*.example.com) | Requires provider-specific credentials |
Worked Example: HTTP-01 Implementation
This example assumes Traefik v2.x or v3.x running in Docker. We will configure a resolver named myresolver using the HTTP-01 challenge.
Step 1: Static Configuration
Run this on your Traefik host. Ensure the acme.json file exists and has restricted permissions, or Traefik will fail to start for security reasons.
# Run as root or a user with sudo privileges
touch acme.json
chmod 600 acme.json
Add these flags to your Traefik startup command or traefik.yml:
--certificatesresolvers.myresolver.acme.httpchallenge=true
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
--certificatesresolvers.myresolver.acme.email=[contact removed]
--certificatesresolvers.myresolver.acme.storage=/acme.json
Step 2: Dynamic Configuration (Docker Labels)
Apply these labels to the service you want to secure. This tells Traefik to use the myresolver defined in the static config.
labels:
- "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=myresolver"
- "traefik.http.routers.myapp.tls=true"
Critical Limitations and Risks
Automated TLS is powerful, but it introduces specific risks:
- Rate Limiting: Let's Encrypt imposes strict limits on how many certificates can be issued per domain per week. If you frequently destroy and recreate your Traefik instance without persisting the
acme.jsonfile, you may be blocked. Always mountacme.jsonas a persistent volume. - The Port 80 Dependency: For HTTP-01 challenges, the CA must be able to reach your server on port 80. If your corporate firewall blocks port 80, you must switch to DNS-01 validation.
- Permission Failures: If
acme.jsonis world-readable, Traefik will log a fatal error and refuse to boot to protect your private keys.
Verification and Testing
To verify the setup, check the Traefik logs for messages containing "ACME" and "certificate obtained". You can also run a curl command to check the certificate expiration date:
# Run from any terminal with access to the domain
curl -vI https://app.example.com 2>&1 | grep "expire date"
If the date is roughly 90 days in the future, the automation is functioning correctly.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.