Automating HTTPS with Traefik’s Let's Encrypt ACME Provider
Learn how to configure Traefik to obtain and renew Let's Encrypt certificates automatically, with a concrete example and practical verification steps.
16 May 2026, 03:35 UTC

Problem: Manual TLS management adds operational overhead
When running containerized services, teams often need to provision TLS certificates for each host. Doing this manually—generating keys, requesting certificates, and remembering to renew them—creates toil and increases the risk of expired certificates causing service disruption.
Thesis: Traefik’s built‑in ACME provider can eliminate that overhead by automatically obtaining and renewing Let's Encrypt certificates
Traefik can act as its own certificate authority client. By configuring an ACME resolver, Traefik will perform the required HTTP‑01 or TLS‑ALPN‑01 challenge, store the resulting certificate, and renew it when it approaches expiry—all without restarting the proxy.
How the ACME provider works in Traefik
When a router defines a rule that matches a host and sets tls.certResolver to a resolver name, Traefik:
- Looks up the resolver configuration (email, storage file, CA server).
- If no valid certificate exists for the host, it initiates an ACME challenge via the entrypoint that exposes port 80 (HTTP‑01) or 443 (TLS‑ALPN‑01).
- Upon successful validation, Let's Encrypt returns a certificate, which Traefik stores in the referenced JSON file.
- For subsequent requests, Traefik serves the stored certificate.
- When the certificate is within 30 days of expiry, Traefik repeats the challenge automatically, using the existing certificate to keep traffic flowing during renewal.
Configuration example (static file)
Below is a minimal traefik.yml that enables an ACME resolver called myresolver and defines a router for a service named whoami.
# traefik.yml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false
certificatesResolvers:
myresolver:
acme:
email: "[contact removed]"
storage: "acme.json"
caServer: "https://acme-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: web
# Dynamic configuration via Docker labels (docker-compose.yml)
services:
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certResolver=myresolver"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
Key points:
- The
acme.jsonfile must be persisted (e.g., mounted volume) so all Traefik replicas can read and write to it. - The HTTP‑01 challenge uses the
webentrypoint on port 80; ensure that port is publicly reachable. - Each service only needs the three labels shown; Traefik handles the rest.
Renewal behavior and trade‑offs
Traefik checks the
notAfterfield in the stored certificate. If the certificate is valid for more than 30 days, no action is taken. Once the validity drops below 30 days, Traefik repeats the ACME challenge. While the old certificate remains valid, the new one is fetched and swapped in seamlessly.Limitations to consider:
- Shared storage requirement: In a multi‑replica deployment, all instances must access the same
acme.json. Using a network filesystem, Consul, etcd, or a cloud‑based object store prevents duplicate challenges and rate‑limit hits. - Let's Encrypt rate limits: The service enforces a limit of 50 certificates per registered domain per week. Aggressive scaling that creates many short‑lived subdomains (e.g., per‑preview environments) can trigger temporary bans. Mitigate by consolidating domains or using a staging CA during development.
- Challenge type dependency: HTTP‑01 requires port 80 to be open. If your environment blocks inbound HTTP, you must switch to TLS‑ALPN‑01 (requires port 443) or DNS‑01 (requires an external DNS provider plugin).
Practical way to verify the setup:
- Deploy Traefik with the configuration above.
- Ensure DNS for
whoami.example.compoints to the host’s public IP. - Run
curl -I https://whoami.example.comfrom an external machine; you should receive a 200 response and theStrict-Transport-Securityheader if configured. - Inspect the
acme.jsonfile; it will contain aCertificateobject with the domain and a timestamp. - To test renewal without waiting, temporarily set the system clock ahead by 35 days (or adjust the
NotAfterfield in a copy of the file) and restart Traefik; the logs should show a new ACME challenge and an updated certificate inacme.json.
Actionable closing
By enabling Traefik’s ACME provider, you replace manual TLS provisioning with an automated, self‑healing process. Start with a single service, verify the challenge flow and storage, then expand to other services using the same resolver. Keep an eye on shared storage and rate limits, and you’ll maintain valid HTTPS certificates with minimal operational overhead.
- Shared storage requirement: In a multi‑replica deployment, all instances must access the same
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.