DEV Community

Peon Sh
Peon Sh

Posted on

Free SSL for Docker Apps: Let’s Encrypt Automation Explained

What happens behind the scenes with automatic HTTPS: ACME challenges, Traefik and Caddy certificate automation, renewal, and the rate limiting you need to circumvent.

From paying $100 for certificates to automation for free
Certificates issued by Let's Encrypt are trusted by all browsers and provided for free and in just seconds through a process called ACME. The purposefully short lifespan of 90 days makes sure that automation is not merely desirable but absolutely necessary. This is exactly why the modern configuration does not deal with certificates at all.

ACME Validation process
Let's Encrypt needs to verify that you are controlling the domain before issuing. Two challenge methods are practically relevant:

HTTP-01: the CA will access http://yourdomain/.well-known/acme-challenge/ from your proxy. Needs port 80 and proper DNS setup pointing at your server. This is the default challenge type for almost all applications

DNS-01: you need to add a TXT record instead; necessary for wildcard certificates ( *. example.com ); doesn’t need port 80 exposed but does require access to the DNS provider API

The architecture that enables it to be automatic
Only one container, acting as a proxy (Traefik or Caddy), holds ports 80 and 443 of the entire server. Whenever a deployment defines a domain for a service through Docker labels behind the scenes, the proxy creates a route, responds to the challenge through ACME on the next request, caches the certificates (acme.json for Traefik), and schedules renewals about 30 days before expiration.

That is precisely how things go down when you type a domain in a Peon service: DNS is all the manual part while the rest becomes machinery you never have to deal with again.

Prerequisites responsible for 90% of problems
DNS resolution has to be set to the server before initial deployment: verify with dig +short app.example.com to your server IP address

Ports 80 AND 443 have to be opened in the cloud firewall and any host firewall; HTTP-01 requires port 80 specifically

If behind Cloudflare’s orange-cloud proxy: set SSL mode to Full (strict), or use grey-cloud temporarily during first certificate issuance; with Full (strict): Cloudflare to origin uses your Let’s Encrypt certificate and browsers see Cloudflare edge certificate

Only one process can listen to port 80: accidental nginx or Apache running on the host prevents all challenges

Rate limits: know them before you loop
The rate limits set by Let’s Encrypt only affect those that are looping over failed attempts: 50 certificates per registered domain per week, 5 duplicate certificates per week, and 5 failed validation attempts per account/hostname per hour. In the event of failure, look at the proxy log (which is quite precise on what is going wrong in the ACME error message), solve the problem, and try again. For experiments and continuous integration, use the staging endpoint.

Top comments (0)