From 642a805d8ae1496abc1eed20462a34058b24107c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Joann=20M=C3=B5ndresku?= Date: Sun, 3 Sep 2023 13:09:13 +0300 Subject: [PATCH] Moving from nginx to Caddy --- content/posts/moving-from-nginx-to-caddy.md | 137 ++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 content/posts/moving-from-nginx-to-caddy.md diff --git a/content/posts/moving-from-nginx-to-caddy.md b/content/posts/moving-from-nginx-to-caddy.md new file mode 100644 index 0000000..898c691 --- /dev/null +++ b/content/posts/moving-from-nginx-to-caddy.md @@ -0,0 +1,137 @@ +--- +title: "Moving from nginx to Caddy" +date: 2023-09-03T13:00:00+03:00 +description: "I describe my journey into using Caddy and the great config truncation from 2000+ lines by 20x" +tags: [site, news] +type: blog +draft: false +--- + +# Backstory +I've heard of [Caddy](https://caddyserver.com/) for a long while, but have always been dismissive about it - ignoring it as "yet another webserver software" when I had my +perfectly good trusty nginx to rely on for many years already. Over the years, my nginx config has become somewhat bloated and even take a while +to do restarts on due to the complexity of said config. I did attempt to resolve it by reducing amount of expensive routines - which did help to +an extent - I was complacent with my setup. Until I took a deeper dive into Caddy. + +One Saturday night (...yesterday as of writing this post), BieHDC brought to my attention that Caddy has a nginx configuration adapter. +I thought to myself why not try it out if it's really plug-and-play and try to see what all the fuss is about. What followed this was all worth it. + +## The nginx-adapter +I started off with building the [nginx adapter for Caddy](https://github.com/caddyserver/nginx-adapter) which took a while. +Very quickly after building it, I ran into issues - no matter what I did, I kept getting null routes on the generated output with no idea where it's coming from. +You would think I would have stopped here, but I foolishly tried to make it work for something that was never meant to be, you see, I forgot to do +one key thing before even starting this whole thing - RTFM (Read The Fucking Manual). The README had a list of directives it supported and I had a ton of which +were not supported, but very essential to the work of my services. + +I shelved the nginx-adpater for good at this point, after wasting an hour with it. + +## The story doesn't end +While I may have been burnt by the mischiefs of nginx-adapter, I wasn't ready to give up - by this point I had already familiarised myself with Caddy's +documentation and reference syntax. I decided to give it a try for based.quest at very least to have a fair and honest impression of Caddy as a software +so I wouldn't start to bash on it going forward from a bad experience on a beta-phase config adapter. + +In literally a few minutes, I had made it, the Caddyfile for based.quest - I present it to you in all its glory in this blogpost: +``` +http://based.quest, based.quest { + root * /var/www/based.quest/html + file_server +} + +breezewiki.based.quest { + reverse_proxy localhost:10416 +} + +rimgo.based.quest { + reverse_proxy localhost:3000 +} + +proxitok.based.quest { + reverse_proxy localhost:8999 +} + +quetre.based.quest { + reverse_proxy localhost:3333 +} +``` + +Yes, you are seeing this right - **this little configuration only needed**. I was shocked. All this time I had been writing more for no reason, because I +turned a blind eye to the alternative that was right in front of me for many years - I've seen the name, I've seen it used in several applications that +I host under Docker, but never gave it a shot until it was pointed out to me that an adapter exist to load nginx configs (which obviously didn't work out, but +that's beside the point). + +## The main server +I wasn't going to stop with only based.quest server - after seeing the potential, I took on the seemingly herculean task of porting my main server's 2000+ lines +of nginx config to a Caddyfile. I delved into documentation for over an hour, searching for answers for any immediate question I had. + +You may find what I wrote useful for your own configs, so here are (not fully mine) templates you can use for building your own Caddy virtualhosts: +``` +(errors) { + handle_errors { + @custom_err file /err-{err.status_code}.html /err.html + handle @custom_err { + rewrite * {file_match.relative} + file_server + } + respond "{err.status_code} {err.status_text}" + } +} +(php-fpm) { + encode gzip + php_fastcgi unix//run/php/php7.4-fpm.sock { + try_files {path} {path}/index.php =404 + } + file_server +} +(cache-static) { + @static { + file + path *.ico *.css *.js *.gif *.webp *.avif *.jpg *.jpeg *.png *.svg *.woff *.woff2 + } + header @static Cache-Control max-age=1209600 +} +``` +You can find most of this on the official documentation, but thought it may be useful to consolidate it here for your convenience. + +Migrating Matrix is super easy, but be attentive to details, they provide the Caddyfile samples on their own repository already - here is my final variant of it: +``` +http://cernodile.com, cernodile.com, cernodile.com:8448 { + header /.well-known/matrix/* Content-Type application/json + header /.well-known/matrix/* Access-Control-Allow-Origin * + respond /.well-known/matrix/server `{"m.server": "cernodile.com"}` + respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"https://cernodile.com"}}` + reverse_proxy /_matrix/* localhost:8008 + reverse_proxy /_synapse/* localhost:8008 + # [...] +} +``` + +The reason I ask you to be attentive to details is because I broke my federation with it. Notice the /matrix/server field. I had copied the sample from Synapse +repository and left it as `"cernodile.com:443"` whereas my **original** well-known record was just `"cernodile.com"`. + +There were 2 blockers when migrating my services to Caddy. PeerTube and Gitweb. Unfortunately for PeerTube, since [PeerTube does not support anything else than nginx](https://docs.joinpeertube.org/install/any-os#webserver), +I had to keep one nginx virtualhost up and use reverse_proxy directive against it. As for Gitweb which doesn't supply any other configuration than +for Apache, I did manage to port it over to Caddy by adapting generic fastcgi adapter in a way that works for Gitweb, feel free to use it as well: +``` +git.based.quest { + root * /usr/share/gitweb + try_files {uri} index.cgi + handle /static/* { + file_server + } + reverse_proxy unix//var/run/fcgiwrap.socket { + transport fastcgi { + env GITWEB_CONFIG /etc/gitweb.conf + split .cgi + } + } +} +``` + +## Closing thoughts +After all this effort, I am down to 108 lines on my Caddyfile from 2000+ lines on nginx. The performance is as great as ever with no hickups noticed. +I want to thank BieHDC for bringing this to my attention, I wouldn't have probably gone down this rabbit hole if it weren't for the nginx adapter. +This experience was all the worth it and I suggest you give Caddy a try if you are currently running an nginx site - you won't regret having to write +20x less configuration for your webserver. + +Thank you for reading +- Cernodile -- 2.25.1