Replacing nginx with Caddy: One Year Later

TL;DR: My updated Caddyfile.

I feel like reviews of a product a few months or even a year out aren't done that often so I'm going to look at Caddy again. I've been using the new hotness known as Caddy for a little over a year now. Last year I replaced my nginx webserver with Caddy. I recently "broke" my webserver so I figure this is a good time to look at Caddy again.

Overall, Caddy is still great. The documentation is really simple. A really simple server config can look like this.

golf1052.com

Give that file to caddy and you have a webserver serving your site over https. If you don't believe me watch this video. My current Caddyfile is a little more complicated because I still have tons of random things running on my DigitalOcean server and because I still love subdomains.

The first problem that arose was when I attempted to add two more subdomains to my Caddyfile. The problem wasn't the subdomains, the problem was the config for https://hotlinering.com. That site pointed to Close Call but we decided not to renew the domain. Caddy, however, kept trying to renew the cert for the domain because I forgot to remove the domain in my Caddyfile. Completely my fault but Caddy had been hitting the Let's Encrypt rate limit for about a month without me knowing. You may think Caddy would crash or error out if it couldn't renew a cert but Caddy kept running fine. The problem arose when I went to restart Caddy after changing my Caddyfile. Caddy won't start if it runs into a rate limit error from Let's Encrypt so now my website and all my projects were inaccessible and I needed things running for one of my school projects. After trying various things I just turned off https for all my domain blocks and Caddy started running again.

It's been 2 days since #caddycrisis and I've fixed Caddy as well as upgraded Caddy from 0.8.2 to 0.10 so I feel like it would be a good time to go over what I've changed.

Read release notes and upgrade to the first version of a major version before upgrading to the latest version.

I learned this from upgrading Ghost manually but I feel like this can hold true for other things. Caddy 0.9 introduced some breaking changes. The thing that I cared most about was the Caddy certificate folder change. 0.9 changed how the cert folder was labeled and organized. Caddy would do the migration for you but I feel like it would be risky to jump straight to the latest version without doing the migration with 0.9 first.

0.9 also deprecated proxy_header for the proxy block which I used for passing host info through to my backend apps. However 0.9 also added transparent which does that all for you. transparent is shorthand for

header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Proto {scheme}

0.9.5 removed proxy_header completely.

Another thing I had to change was my redirect blocks. I use HTTP response status code 302 (Found/Moved Temporarily) instead of 301 (Moved Permanently) because I had some issues in the past with changing where my subdomains point to if I change the redirect link. My subdomain redirects weren't working and the reason was that I needed to specify the from request path if I was also specifying the status code. / is a catch all so
redir https://golf1052.com/documents/sanders_lauture_resume.pdf 302
turns into
redir / https://golf1052.com/documents/sanders_lauture_resume.pdf 302.

Some of my error blocks also had to change. Instead of specifying a log block inside the error block I could just specify the log file location on the error block line. Rotate also changed, rotate changed from a block to 3 lines instead. See my revised Caddyfile at the end of the post.

My Caddyfile was now working great with Caddy 0.10 but I noticed that Chrome was auto redirecting my main site from http to https but Edge wasn't. After a little reading I found the best way to fix this was to add this block.

http://www.golf1052.com, http://golf1052.com {
    redir / https://golf1052.com{uri} 301
}

{uri} preserves the request URI.

The last thing that bothered me was that some links would display .html in the address bar. ext was the solution. Now when nobody goes to my terrible looking Twixel privacy policy page their eyes wont be assaulted by the .html in the address bar.

I originally gave Caddy a cautious 👌🏾 but now I would give Caddy an enthusiastic 👏🏾.

Caddyfile revisions
New Caddyfile