Automatic HTTPS

Activate automatic HTTPS

Understand how a hostname activates certificate management and HTTP-to-HTTPS redirects.

Give Caddy a domain name and it gets a TLS certificate, renews it forever, and redirects HTTP to HTTPS. This is the feature Caddy is known for. It’s called automatic HTTPS, and you turn it on by writing a hostname.

blog.example.com {
  respond "hello over HTTPS"
}

That’s the whole configuration. When Caddy sees a hostname like this as the site address, it asks an ACME certificate authority for a certificate. ACME is the protocol Let’s Encrypt and ZeroSSL use to issue certificates automatically. Caddy answers the validation challenge, installs the certificate, and schedules the renewal. It also redirects port 80 to port 443 for that name.

The trigger is the address

Nothing else turns the feature on or off. Compare these two sites:

http://app.example.test {
  respond "HTTP only"
}

blog.example.com {
  respond "automatic HTTPS"
}

The explicit http:// scheme opts the first site out. The bare hostname opts the second one in.

Addresses like :8080 don’t trigger public issuance either, because there’s no name to certify. And localhost gets a locally trusted certificate instead of a public one. That’s the next lesson.

Study it without a domain

You don’t need to own a domain to see what Caddy does. Adapt the configuration and read the JSON:

caddy adapt --config Caddyfile --pretty

Look for the TLS automation policies and the HTTP-to-HTTPS redirect route. You wrote one line. Caddy generated all of that.

What production needs

For issuance to work on a real server, two things must be true. DNS for the name points at your server. Ports 80 and 443 reach Caddy.

That’s it. No renewal cron job, no certbot, nothing to remember in three months. This is the reason I recommend Caddy to anyone running a small VPS: certificate expiry stops being a thing you think about.

Use the staging CA while testing

Now the mistake that bites beginners: testing against the real Let’s Encrypt endpoint over and over. Production CAs enforce rate limits. Restart a broken setup twenty times and you can get locked out of issuance for days.

While you’re testing, point Caddy at the staging CA:

blog.example.com {
  tls {
    ca https://acme-staging-v02.api.letsencrypt.org/directory
  }
  respond "testing issuance"
}

Browsers don’t trust staging certificates. But issuance succeeds or fails for the same reasons as production, so you can debug DNS and ports freely. Once the staging flow works, remove the ca line and let Caddy get the real certificate once.

Lesson completed