Commit | Line | Data |
---|---|---|
642a805d JM |
1 | --- |
2 | title: "Moving from nginx to Caddy" | |
3 | date: 2023-09-03T13:00:00+03:00 | |
4 | description: "I describe my journey into using Caddy and the great config truncation from 2000+ lines by 20x" | |
5 | tags: [site, news] | |
6 | type: blog | |
7 | draft: false | |
8 | --- | |
9 | ||
10 | # Backstory | |
11 | 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 | |
12 | 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 | |
13 | 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 | |
14 | an extent - I was complacent with my setup. Until I took a deeper dive into Caddy. | |
15 | ||
16 | One Saturday night (...yesterday as of writing this post), BieHDC brought to my attention that Caddy has a nginx configuration adapter. | |
17 | 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. | |
18 | ||
19 | ## The nginx-adapter | |
20 | I started off with building the [nginx adapter for Caddy](https://github.com/caddyserver/nginx-adapter) which took a while. | |
21 | 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. | |
22 | 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 | |
23 | 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 | |
24 | were not supported, but very essential to the work of my services. | |
25 | ||
26 | I shelved the nginx-adpater for good at this point, after wasting an hour with it. | |
27 | ||
28 | ## The story doesn't end | |
29 | 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 | |
30 | 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 | |
31 | so I wouldn't start to bash on it going forward from a bad experience on a beta-phase config adapter. | |
32 | ||
33 | 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: | |
34 | ``` | |
35 | http://based.quest, based.quest { | |
36 | root * /var/www/based.quest/html | |
37 | file_server | |
38 | } | |
39 | ||
40 | breezewiki.based.quest { | |
41 | reverse_proxy localhost:10416 | |
42 | } | |
43 | ||
44 | rimgo.based.quest { | |
45 | reverse_proxy localhost:3000 | |
46 | } | |
47 | ||
48 | proxitok.based.quest { | |
49 | reverse_proxy localhost:8999 | |
50 | } | |
51 | ||
52 | quetre.based.quest { | |
53 | reverse_proxy localhost:3333 | |
54 | } | |
55 | ``` | |
56 | ||
57 | 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 | |
58 | 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 | |
59 | 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 | |
60 | that's beside the point). | |
61 | ||
62 | ## The main server | |
63 | 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 | |
64 | of nginx config to a Caddyfile. I delved into documentation for over an hour, searching for answers for any immediate question I had. | |
65 | ||
66 | 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: | |
67 | ``` | |
68 | (errors) { | |
69 | handle_errors { | |
70 | @custom_err file /err-{err.status_code}.html /err.html | |
71 | handle @custom_err { | |
72 | rewrite * {file_match.relative} | |
73 | file_server | |
74 | } | |
75 | respond "{err.status_code} {err.status_text}" | |
76 | } | |
77 | } | |
78 | (php-fpm) { | |
79 | encode gzip | |
80 | php_fastcgi unix//run/php/php7.4-fpm.sock { | |
81 | try_files {path} {path}/index.php =404 | |
82 | } | |
83 | file_server | |
84 | } | |
85 | (cache-static) { | |
86 | @static { | |
87 | file | |
88 | path *.ico *.css *.js *.gif *.webp *.avif *.jpg *.jpeg *.png *.svg *.woff *.woff2 | |
89 | } | |
90 | header @static Cache-Control max-age=1209600 | |
91 | } | |
92 | ``` | |
93 | You can find most of this on the official documentation, but thought it may be useful to consolidate it here for your convenience. | |
94 | ||
95 | 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: | |
96 | ``` | |
97 | http://cernodile.com, cernodile.com, cernodile.com:8448 { | |
98 | header /.well-known/matrix/* Content-Type application/json | |
99 | header /.well-known/matrix/* Access-Control-Allow-Origin * | |
100 | respond /.well-known/matrix/server `{"m.server": "cernodile.com"}` | |
101 | respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"https://cernodile.com"}}` | |
102 | reverse_proxy /_matrix/* localhost:8008 | |
103 | reverse_proxy /_synapse/* localhost:8008 | |
104 | # [...] | |
105 | } | |
106 | ``` | |
107 | ||
108 | 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 | |
109 | repository and left it as `"cernodile.com:443"` whereas my **original** well-known record was just `"cernodile.com"`. | |
110 | ||
111 | 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), | |
112 | 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 | |
113 | 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: | |
114 | ``` | |
115 | git.based.quest { | |
116 | root * /usr/share/gitweb | |
117 | try_files {uri} index.cgi | |
118 | handle /static/* { | |
119 | file_server | |
120 | } | |
121 | reverse_proxy unix//var/run/fcgiwrap.socket { | |
122 | transport fastcgi { | |
123 | env GITWEB_CONFIG /etc/gitweb.conf | |
124 | split .cgi | |
125 | } | |
126 | } | |
127 | } | |
128 | ``` | |
129 | ||
130 | ## Closing thoughts | |
131 | 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. | |
132 | 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. | |
133 | 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 | |
134 | 20x less configuration for your webserver. | |
135 | ||
136 | Thank you for reading | |
137 | - Cernodile |