This is my first post with my blog running Caddy. In short, it’s a web server with a focus on making HTTPS simple. It accomplishes this by supporting ACME out of the box. ACME is the protocol that Let’s Encrypt uses. Technically, Caddy supports any Certificate Authority that supports ACME. Practically, few besides Let’s Encrypt do, though I am aware of other CAs making an effort to support issuance with ACME.

Though I’ve seen lots of praise for Caddy and its HTTPS ALL THE THINGS mantra for a while now, I never really dug in to it until recently. I was actually grabbed by several of its other features that I really liked.

Configuration is simple. That isn’t always a good thing. Simple usually means advanced configuration or features is lost in the trade off. Fortunately, this does not seem to be the case with Caddy, for me. I am sure it may be for others. When evaluating Caddy, there were a number of things nginx was taking care of besides serving static content.

  1. Rewrite to WebP if the user agent accepts WebP.
  2. Serve pre-compressed gzip files if the user agent accepts it.
  3. Serve pre-compressed brotli files if the user agent accepts it.
  4. Take care of some simple redirects.
  5. Flexible TLS configuration around cipher suites, protocols, and key exchanges.

Caddy does all of those. It also does them better. Points two and three Caddy just does. It’ll serve gzip or brotli if the user agent is willing to accept them if a pre-compressed version of the file is on disk.

Rewriting to WebP was easy:

header /images {
    Vary Accept

rewrite /images {
    ext .png .jpeg .jpg
    if {>Accept} has image/webp
    to {path}.webp {path}

The configuration does two things. First, it adds the Vary: Accept header to all responses under /images. This is important if a proxy or CDN is caching assets. The second part says, if the Accept header contains “image/webp”, rewrite the response to “{path}.webp”, so it will look for “foo.png.webp” if a browser requests “foo.png”. The second {path} means use the original if there is no webp version of the file. Nginx on the other hand, was a bit more complicated.

HTTPS / TLS configuration is simple and well documented. As the documentation points out, most people don’t need to do anything other than enable it. It has sensible defaults, and will use Let’s Encrypt to get a certificate.

I’m optimistic about Caddy. I think it’s a very nice web server / reverse proxy. I spent about an hour moving my 400 lines of nginx configuration to 51 lines of Caddy configuration.

I’d recommend giving it a shot.