ACME (Let’s Encrypt)
Traefik can automatically generate and renew TLS certificates from ACME providers like Let’s Encrypt, enabling zero-configuration HTTPS.
Let’s Encrypt has rate limits that last up to one week and cannot be overridden. Use the staging server during development to avoid hitting these limits.
Certificate Resolvers
Certificate resolvers are defined in the static configuration and handle certificate retrieval from ACME servers:
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
caServer: https://acme-v02.api.letsencrypt.org/directory
# Choose one challenge type:
httpChallenge:
entryPoint: web
Defining a certificate resolver does not automatically apply it to all routers. Each router must explicitly reference the resolver using tls.certResolver.
Configuration Options
Required Options
| Option | Description | Example |
|---|
email | Email address for registration and recovery contact | [email protected] |
storage | File path to store ACME data and certificates | acme.json or /acme/acme.json |
| Challenge | One of: httpChallenge, tlsChallenge, or dnsChallenge | See challenge sections below |
Optional Options
| Option | Default | Description |
|---|
caServer | Let’s Encrypt Production | ACME server URL |
keyType | RSA4096 | Certificate key type: EC256, EC384, RSA2048, RSA4096, RSA8192 |
certificatesDuration | 2160 (90 days) | Certificate duration in hours |
preferredChain | - | Preferred certificate chain to use |
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
keyType: EC384
certificatesDuration: 2160
tlsChallenge: {}
ACME Challenges
ACME providers use challenges to verify domain ownership. You must configure exactly one challenge type.
HTTP-01 Challenge
The HTTP-01 challenge provisions an HTTP resource to verify domain ownership.
Requirements
Port 80 must be reachable by Let’s Encrypt servers.
Advantages
- Works with standard HTTP
- Easy to set up
- Compatible with HTTP redirects
Limitations
- Cannot issue wildcard certificates
- Requires port 80 to be accessible
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
httpChallenge:
entryPoint: web
TLS-ALPN-01 Challenge
The TLS-ALPN-01 challenge uses TLS with the ALPN extension to verify domain ownership.
Requirements
Port 443 must be reachable by Let’s Encrypt servers.
Advantages
- Works on port 443
- No need for port 80
- Fast validation
Limitations
- Cannot issue wildcard certificates
- Requires port 443 to be accessible
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
tlsChallenge: {}
DNS-01 Challenge
The DNS-01 challenge provisions a DNS TXT record to verify domain ownership.
Requirements
Access to DNS provider API and credentials.
Advantages
- Supports wildcard certificates
- No ports need to be publicly accessible
- Works behind firewalls
Limitations
- Requires DNS provider integration
- Slower validation process
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Popular DNS Providers
Cloudflare
AWS Route53
Google Cloud DNS
DigitalOcean
# Environment variables
CF_DNS_API_TOKEN=your-api-token
# or
CF_API_EMAIL=[email protected]
CF_API_KEY=your-api-key
dnsChallenge:
provider: cloudflare
# Environment variables
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=us-east-1
dnsChallenge:
provider: route53
# Environment variables
GCE_PROJECT=your-project-id
GCE_SERVICE_ACCOUNT_FILE=/path/to/service-account.json
dnsChallenge:
provider: gcloud
# Environment variables
DO_AUTH_TOKEN=your-auth-token
dnsChallenge:
provider: digitalocean
See the lego documentation for a complete list of supported DNS providers and required environment variables.
Domain Configuration
Single Domain from Router Rule
Traefik automatically extracts the domain from the Host() matcher:
http:
routers:
my-router:
rule: "Host(`example.com`)"
service: my-service
tls:
certResolver: myresolver
Multiple Domains (SANs)
Multiple Host() matchers create a single certificate with Subject Alternative Names:
http:
routers:
my-router:
rule: "Host(`example.com`) || Host(`www.example.com`)"
service: my-service
tls:
certResolver: myresolver
Explicit Domain Configuration
Specify domains explicitly using tls.domains:
http:
routers:
my-router:
rule: "Host(`example.com`)"
service: my-service
tls:
certResolver: myresolver
domains:
- main: example.com
sans:
- www.example.com
- admin.example.com
Wildcard Certificates
Wildcard certificates require DNS-01 challenge:
http:
routers:
my-router:
rule: "Host(`example.com`) || HostRegexp(`{subdomain:[a-z]+}.example.com`)"
service: my-service
tls:
certResolver: myresolver
domains:
- main: "*.example.com"
sans:
- example.com
Wildcard certificates (*.example.com) do not cover the root domain (example.com). Add the root domain as a SAN if needed.
Automatic Renewals
Traefik automatically renews certificates before they expire:
- Default certificate duration: 90 days (2160 hours)
- Default renewal period: 30 days before expiration
- Renewal check interval: Daily
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
certificatesDuration: 2160 # 90 days
tlsChallenge: {}
Traefik renews all certificates, even those no longer in use. This behavior may change in future versions.
Storage Configuration
The storage option specifies where ACME data is persisted:
Local File
Docker Volume
Kubernetes
When running in Docker, mount this file as a volume to persist data across container restarts.
# docker-compose.yml
services:
traefik:
image: traefik:v3.0
volumes:
- ./acme:/acme
command:
- --certificatesresolvers.myresolver.acme.storage=/acme/acme.json
# Use a PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: acme-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
External Account Binding (EAB)
Some ACME providers require External Account Binding:
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
caServer: https://acme.example.com/directory
eab:
kid: key-identifier
hmacEncoded: base64-encoded-hmac-key
tlsChallenge: {}
Testing with Let’s Encrypt Staging
Always test with the Let’s Encrypt staging environment first:
certificatesResolvers:
staging:
acme:
email: [email protected]
storage: acme-staging.json
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
tlsChallenge: {}
The staging environment issues certificates from a fake CA. Browsers will show security warnings. Use staging only for testing.
Advanced Configuration
DNS Propagation Settings
Control DNS propagation checks for DNS-01 challenge:
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
dnsChallenge:
provider: cloudflare
propagation:
delayBeforeChecks: 30s
disableANSChecks: false
requireAllRNS: false
Custom CA Certificates
Use custom CA certificates for private ACME servers:
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
caServer: https://acme.internal.example.com/directory
caCertificates:
- /path/to/ca-cert.pem
Troubleshooting
Rate Limit Errors
Check Rate Limits
Let’s Encrypt has limits on certificates per domain (50/week) and failed validation attempts (5/hour).
Use Staging
Test with the staging server which has higher rate limits.
Persist Storage
Ensure acme.json persists across restarts to avoid re-requesting certificates.
Challenge Failures
HTTP-01
TLS-ALPN-01
DNS-01
- Verify port 80 is accessible from the internet
- Check firewall rules
- Ensure the entryPoint is correctly configured
- Verify port 443 is accessible from the internet
- Check firewall rules
- Ensure no other process is using port 443
- Verify DNS provider credentials
- Check DNS propagation with
dig or nslookup
- Increase
delayBeforeChecks if propagation is slow
Enable debug logging to see detailed ACME challenge information: