diff options
Diffstat (limited to '')
| -rw-r--r-- | src/blog/2026-09-05-cgit/cgit.md | 141 | ||||
| -rw-r--r-- | src/blog/2026-09-13-host-migration/host-migration.md | 172 |
2 files changed, 313 insertions, 0 deletions
diff --git a/src/blog/2026-09-05-cgit/cgit.md b/src/blog/2026-09-05-cgit/cgit.md new file mode 100644 index 0000000..29d92ba --- /dev/null +++ b/src/blog/2026-09-05-cgit/cgit.md | |||
| @@ -0,0 +1,141 @@ | |||
| 1 | # From stagit to cgit | ||
| 2 | |||
| 3 | When I first set up this website back in 2022, I also started self-hosting | ||
| 4 | my git repositories. To make them accessible via web I used | ||
| 5 | [stagit](https://codemadness.org/stagit.html), and I wrote about this | ||
| 6 | in [an old blog post](..//2022-11-23-git-host/). In short, I used a custom | ||
| 7 | post-receive [git | ||
| 8 | hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) that used | ||
| 9 | stagit to generate the HTML pages for [my git | ||
| 10 | website](https://stagit.tronto.net). | ||
| 11 | |||
| 12 | This script ran every time I pushed some changes to a repository. | ||
| 13 | After calling stagit, the script would also modify the generated | ||
| 14 | pages to add a custom Download button at the top, which was not | ||
| 15 | efficient. For my largest repositories, this took around | ||
| 16 | a couple of minutes for every `git push`. Moreover, having all the file | ||
| 17 | contents both in the git folder and in the HTML pages wasted some | ||
| 18 | space on my small VM. | ||
| 19 | |||
| 20 | So I looked for alternatives, and I found | ||
| 21 | [cgit](https://git.zx2c4.com/cgit/about/), which works quite differently | ||
| 22 | from stagit. I gave it a try, and I am quite happy with the result! If | ||
| 23 | you want to check it out, go to [git.tronto.net](https://git.tronto.net). | ||
| 24 | A frozen version of the old stagit-generated pages is still available at | ||
| 25 | [stagit.tronto.net](https://stagit.tronto.net). | ||
| 26 | |||
| 27 | ## Static pages versus CGI | ||
| 28 | |||
| 29 | Instead of generating pages to be served by a | ||
| 30 | [web server](https://en.wikipedia.org/wiki/Web_server), cgit is | ||
| 31 | based on [CGI](https://en.wikipedia.org/wiki/Common_Gateway_Interface). | ||
| 32 | To put it simply, cgit is a program that continuously runs on a server, | ||
| 33 | generating on the fly each page a visitor requests. | ||
| 34 | |||
| 35 | There is an obvious trade-off between disk space and CPU usage here: | ||
| 36 | on the one hand we don't need to store all the HTML pages that are | ||
| 37 | essentially a duplicate of what can already be found in the git | ||
| 38 | repository's folder; on the other hand, computing the page on the | ||
| 39 | go takes some work for the server's CPU. However, cgit can also | ||
| 40 | cache the most recently viewed pages, so it does not have to re-compute | ||
| 41 | the most requested ones all that often. | ||
| 42 | |||
| 43 | Of course, another cost is the more complex setup, as we are now dealing with | ||
| 44 | a full-blown web application instead of plain and simple static HTML files. | ||
| 45 | We'll get into some of the problems that this causes in the next section. | ||
| 46 | |||
| 47 | ## OpenBSD and cgit | ||
| 48 | |||
| 49 | As you may know, the [VM](https://en.wikipedia.org/wiki/Virtual_machine) | ||
| 50 | that hosts this website has historically been running on | ||
| 51 | [OpenBSD](https://openbsd.org) (spoiler: this is no longer the case). | ||
| 52 | When it comes to hosting cgit, or any CGI application, this comes with | ||
| 53 | some pros and some cons. | ||
| 54 | |||
| 55 | First off, the pros: OpenBSD's base system already has a web server | ||
| 56 | ([httpd](https://man.openbsd.org/httpd.8)) and a FastCGI server | ||
| 57 | ([slowcgi](https://man.openbsd.org/slowcgi.8)) that are capable of | ||
| 58 | running cgit. So no external program is strictly needed other than | ||
| 59 | cgit itself - see [this short | ||
| 60 | tutorial](https://codemadness.org/openbsd-httpd-and-cgit.html) for | ||
| 61 | details. | ||
| 62 | |||
| 63 | But there are some points of friction that arise from one of httpd's | ||
| 64 | most-loved security features: the fact that it works in a | ||
| 65 | [chroot](https://en.wikipedia.org/wiki/Chroot) environment, by default | ||
| 66 | rooted at `/var/www`. This means that httpd cannot see any file outside | ||
| 67 | of `/var/www`. So any file that cgit needs, including all the git | ||
| 68 | repositories that one wants to show, must be inside `/var/www`. | ||
| 69 | |||
| 70 | And while it is not much effort to put them there, I have been | ||
| 71 | managing my repositories via a dedicated `git` user, keeping them in | ||
| 72 | `/home/git`. So I would have to either change this user's home directory | ||
| 73 | to something in `/var/www`, or change the relative path of each repository. | ||
| 74 | Either way, it wouldn't be as nice as my current setup. | ||
| 75 | |||
| 76 | But the repositories are not all cgit may want to know about. For example, | ||
| 77 | one can *filter* README files through a Markdown parser, such as | ||
| 78 | [lowdown](https://kristaps.bsd.lv/lowdown/), to display more nicely on the | ||
| 79 | web - see [this README](https://git.tronto.net/nissy-core/about/) for an | ||
| 80 | example. The parser, too, must live within httpd's chroot. Same for any | ||
| 81 | [dynamic library](https://en.wikipedia.org/wiki/Dynamic_library) it | ||
| 82 | depends on. To make this work, I ended up creating `usr/bin` and `usr/lib` | ||
| 83 | folders inside `/var/www` and manually copied some executables and libraries | ||
| 84 | there - not the cleanest solution. | ||
| 85 | |||
| 86 | Alternatively, one may configure httpd to chroot at `/`, making things | ||
| 87 | more practical but loosing the security benefits. But at this point, | ||
| 88 | I decided I wanted to try out a different stack - new VPS provider, new | ||
| 89 | OS, new web server. This is something I had been thinking about for | ||
| 90 | about a year at this point, and I'll talk about the reasons in [my | ||
| 91 | next post](../2026-09-13-host-migration). | ||
| 92 | |||
| 93 | But if you plan to host cgit on OpenBSD, do not be discouraged! | ||
| 94 | Everything can be set up with just a little manual work. | ||
| 95 | |||
| 96 | ## My cgit configuration | ||
| 97 | |||
| 98 | My new cgit instance is hosted on an [Alpine Linux](https://alpinelinux.org) | ||
| 99 | VM and it is running via [Lighttpd](https://www.lighttpd.net). | ||
| 100 | For the basic setup, I followed [this wiki | ||
| 101 | page](https://wiki.alpinelinux.org/wiki/Cgit) (note that lighttpd has a | ||
| 102 | `mod_cgi` module that replaces fcgiwrap entirely). Not much | ||
| 103 | to say here, just a little fiddling with lighttpd's configuration. | ||
| 104 | |||
| 105 | As for customization, my configuration files are available in my | ||
| 106 | [cgit-config](https://git.tronto.net/cgit-config) repository. The | ||
| 107 | main configuration file, | ||
| 108 | [cgitrc](https://git.tronto.net/cgit-config/tree/cgitrc), is | ||
| 109 | well-commented, and won't require further explanation. | ||
| 110 | |||
| 111 | There are a bunch of other files too, such as the custom | ||
| 112 | [about-filter.sh](https://git.tronto.net/cgit-config/tree/custom/about-filter.sh) | ||
| 113 | which, is used to display README files more nicely. As for the custom | ||
| 114 | [css](https://git.tronto.net/cgit-config/tree/custom/cgit.css), the | ||
| 115 | main feature is making the website a little more comfortable to | ||
| 116 | browse on mobile; I shamelessly copied this part from [another cgit | ||
| 117 | user](https://git.matejamaric.com/responsive-cgit-css). | ||
| 118 | |||
| 119 | ## Pros and con(cern)s | ||
| 120 | |||
| 121 | So far, cgit seems to run pretty fast on my new VM with a single CPU | ||
| 122 | core and 1GB of RAM. It also looks pretty cool, even though I liked | ||
| 123 | stagit's simplicity. | ||
| 124 | |||
| 125 | Unfortunately, the nice download button that I added to each of my | ||
| 126 | repositories is now gone. cgit allows downloading tarballs of a repo, | ||
| 127 | but only from tags, not for the current state of the master branch. | ||
| 128 | Overall, stagit's simplicity also allowed for great deal of customizability. | ||
| 129 | |||
| 130 | I am also a bit concerned about AI | ||
| 131 | [crawlers](https://en.wikipedia.org/wiki/Web_crawler). I have heard horror | ||
| 132 | stories of people having to make their repositories private because of | ||
| 133 | bots scanning their pages to feed the slop machine overloading their servers. | ||
| 134 | However, I hope cgit being quite small compared to a | ||
| 135 | [forge](https://en.wikipedia.org/wiki/Forge_(software)) such as | ||
| 136 | [GitLab](https://en.wikipedia.org/wiki/GitLab) or | ||
| 137 | [Gitea](https://en.wikipedia.org/wiki/Gitea) will help my server | ||
| 138 | sustain the extra effort - if any bot is interested in my code at all. | ||
| 139 | |||
| 140 | In conclusion, stagit served me well for a while, and I think | ||
| 141 | cgit is better suited to my needs now. | ||
diff --git a/src/blog/2026-09-13-host-migration/host-migration.md b/src/blog/2026-09-13-host-migration/host-migration.md new file mode 100644 index 0000000..72a26ef --- /dev/null +++ b/src/blog/2026-09-13-host-migration/host-migration.md | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | # Host migration | ||
| 2 | |||
| 3 | Since this website went online in 2022, It has lived | ||
| 4 | in a virtual machine on server 14 at [OpenBSD | ||
| 5 | Amsterdam](https://openbsd.amsterdam). This is a small, independent | ||
| 6 | VPS provider that donates large part of their profit to the | ||
| 7 | [OpenBSD foundation](https://www.openbsdfoundation.org). They | ||
| 8 | are pretty cool, and their service worked quite well for me. | ||
| 9 | |||
| 10 | Nonetheless, I have recently migrated to another provider, and I | ||
| 11 | am not going to renew my OpenBSD Amsterdam subscription next year. | ||
| 12 | There are a few reasons for this. | ||
| 13 | |||
| 14 | ## Why switch? | ||
| 15 | |||
| 16 | First of all, I want to make clear that I did not have any issue | ||
| 17 | with OpenBSD Amsterdam. In fact, I think it was the right choice for | ||
| 18 | me 4 years ago, and I can strongly recommend it. | ||
| 19 | |||
| 20 | OpenBSD as well was a great OS choice, at the beginning. | ||
| 21 | The convenience of having many of the services I needed - such as | ||
| 22 | [httpd](https://man.openbsd.org/httpd), | ||
| 23 | [rsync](https://man.openbsd.org/openrsync), | ||
| 24 | [ssh](https://man.openbsd.org/ssh) - included in the base system and | ||
| 25 | well-documented was big. But OpenBSD is also an | ||
| 26 | [opinionated](https://www.merriam-webster.com/dictionary/opinionated) | ||
| 27 | piece of software, | ||
| 28 | and some of its "opinions" started feeling a bit restrictive. | ||
| 29 | |||
| 30 | For example, OpenBSD nudges you into using separate | ||
| 31 | [partitions](https://en.wikipedia.org/wiki/Disk_partitioning) for | ||
| 32 | different system folders, for security reasons. This is how the 50GB | ||
| 33 | of my OpenBSD Amsterdam VM are currently allocated: | ||
| 34 | |||
| 35 | ``` | ||
| 36 | [pizoc ~] $ df -h | ||
| 37 | Filesystem Size Used Avail Capacity Mounted on | ||
| 38 | /dev/sd0a 986M 111M 825M 12% / | ||
| 39 | /dev/sd0k 17.4G 3.9G 12.6G 24% /home | ||
| 40 | /dev/sd0d 3.2G 8.0K 3.0G 1% /tmp | ||
| 41 | /dev/sd0f 5.2G 1.7G 3.3G 34% /usr | ||
| 42 | /dev/sd0g 986M 545M 392M 59% /usr/X11R6 | ||
| 43 | /dev/sd0h 6.7G 184M 6.2G 3% /usr/local | ||
| 44 | /dev/sd0j 5.8G 2.0K 5.5G 1% /usr/obj | ||
| 45 | /dev/sd0i 1.9G 2.0K 1.8G 1% /usr/src | ||
| 46 | /dev/sd0e 5.0G 4.4G 423M 92% /var | ||
| 47 | ``` | ||
| 48 | |||
| 49 | My websites are in `/var/www`, and as you can see that partition | ||
| 50 | is almost full. I also use `/home` extensively - my git repositories | ||
| 51 | are in `/home/git` and a shared | ||
| 52 | [syncthing](https://syncthing.net) folder is in `/home/sebastiano`. | ||
| 53 | I have plenty of space still available in `/home`, but I can't | ||
| 54 | esily use it for hosting websites, because of httpd's chroot. See | ||
| 55 | [my previous post](../2026-09-05-cgit) for details on what this means. | ||
| 56 | |||
| 57 | Another downside of httpd is that it is not as feature-complete | ||
| 58 | as other web server. This can be considered an advantage, but | ||
| 59 | occasionally it requires some extra setup for certain use cases. | ||
| 60 | For example, [until | ||
| 61 | recently](https://undeadly.org/cgi?action=article;sid=20260725103657) | ||
| 62 | it did not support custom HTTP headers, so I had to combine it | ||
| 63 | with relayd when I wanted to experiment with a [web | ||
| 64 | application](https://h48.tronto.net) I was working on - see also | ||
| 65 | [my post on WebAssembly](../2025-06-06-webdev/) for context. | ||
| 66 | Once again, this was not a showstopper, but | ||
| 67 | it was unnecessary additional friction. | ||
| 68 | |||
| 69 | Lastly, my provider was a bit more expensive than I would have | ||
| 70 | liked: 71€ per year for a VM with 1GB of RAM and 50GB of | ||
| 71 | storage. For comparison, I am now paying 22€ per year for | ||
| 72 | a VM with the same RAM and 30GB of storage. To be fair, | ||
| 73 | OpenBSD Amsterdam is a small, independent provider, and they | ||
| 74 | donate a most of their revenuw to the OpenBSD foundation; I was | ||
| 75 | happy to support them. But I am also happy to save 49€ | ||
| 76 | per year. | ||
| 77 | |||
| 78 | ## The new stack | ||
| 79 | |||
| 80 | My new provider is [netcup](https://www.netcup.com/en), an established | ||
| 81 | German company. I don't personally know anyone hosting there, | ||
| 82 | but their prices are good and the reviews are positive. Their [smallest | ||
| 83 | VPS](https://www.netcup.com/en/server/vps-lite) is only 1.87€ per | ||
| 84 | month, and it is enough for my needs. | ||
| 85 | |||
| 86 | They support any operating system that can boot from a | ||
| 87 | [Qcow](https://en.wikipedia.org/wiki/Qcow) image, as you can upload your | ||
| 88 | own; so technically I could have stayed with OpenBSD. But I wanted | ||
| 89 | to change the OS for the reasons I gave in the previous section, so I | ||
| 90 | went with [Alpine Linux](https://alpinelinux.org), a lightweight | ||
| 91 | Linux distribution that I have been pleasantly using on my laptop for a | ||
| 92 | while now. | ||
| 93 | |||
| 94 | As for the web server, I did not give it much thought. | ||
| 95 | [Lighttpd](https://www.lighttpd.net) seems fairly lightweight and it | ||
| 96 | does what I need it to do, so I went with that. | ||
| 97 | |||
| 98 | ## Migration hiccups | ||
| 99 | |||
| 100 | I initially planned to migrate my [git server](../2026-09-05-cgit) | ||
| 101 | and this website one at the time, but soon I realized that it would have | ||
| 102 | been less work and less risk to do everything at once. So I set aside | ||
| 103 | a full Sunday afternoon to move everything over. | ||
| 104 | |||
| 105 | Unfortunately, I had some issues. The biggest one, that took me over | ||
| 106 | three hours to work around, was related to setting up my SSL | ||
| 107 | certificates - the "S" in [HTTPS](https://en.wikipedia.org/wiki/HTTPS). | ||
| 108 | I wanted to use the same software I was using on OpenBSD, | ||
| 109 | [acme-client](https://man.openbsd.org/acme-client.1), but something | ||
| 110 | went wrong. I kept getting an HTTP 409 error with the following | ||
| 111 | explanation: | ||
| 112 | |||
| 113 | ``` | ||
| 114 | acme-client: transfer buffer: [{ | ||
| 115 | "type": "urn:ietf:params:acme:error:conflict", | ||
| 116 | "detail": "Unable to update challenge :: failed to mark authz as processing: Authorization is already being validated. This may indicate your client attempted the same challenge multiple times, possibly due to a client bug.", | ||
| 117 | "status": 409 | ||
| 118 | }] (296 bytes) | ||
| 119 | acme-client: bad exit: netproc(31648): 1 | ||
| 120 | ``` | ||
| 121 | |||
| 122 | Searching online, I found out that I was [not the only | ||
| 123 | one](https://www.reddit.com/r/openbsd/comments/1vz4mcg/acmeclient_bad_http_409) | ||
| 124 | with this problem, so I decided to use [certbot](https://certbot.eff.org) | ||
| 125 | as a temporary workaround. But I still want to go back to | ||
| 126 | acme-client at some point. | ||
| 127 | |||
| 128 | The other issue was AI. And I am not talking about OpenAI's and | ||
| 129 | Anthropic's bots accessing my git pages every 0.9 seconds (that | ||
| 130 | is not an exaggeration, I `tail -f`'d the log file). I am | ||
| 131 | talking about actually trying to use these chatbots for their | ||
| 132 | intended purpose. Namely, instead of reading the manual pages | ||
| 133 | for lighttpd and writing a configuration file from scratch, | ||
| 134 | I asked AI (either [duck.ai](https://duck.ai)) or | ||
| 135 | [Kagi Assistant](https://kagi.com/assistant/), I forgot which one) | ||
| 136 | to translate my httpd configuration file to a lighttpd one. Then | ||
| 137 | I could look up the documentation for just the settings I was | ||
| 138 | using, saving some time. Or so I thought. | ||
| 139 | |||
| 140 | First of all, the initial response had more stuff than | ||
| 141 | I wanted. The bot just allucinated features that were not included | ||
| 142 | in the original configuration. But that's alright, it's just how | ||
| 143 | the slop machine works. | ||
| 144 | |||
| 145 | But then there were also errors, in particular with setting | ||
| 146 | up the redirects from my `http://*.tronto.net` domains to their | ||
| 147 | `https://` counterparts. I went through various iterations of | ||
| 148 | "this does not work, it does X instead of Y, please fix" and | ||
| 149 | "You are absolutely right! Here is the fixed version", | ||
| 150 | but somehow the bots could | ||
| 151 | never come up with a working configuration. I ended up fixing | ||
| 152 | it by hand like a caveman, as I should have done from the | ||
| 153 | beginning. What a waste of time. | ||
| 154 | |||
| 155 | But by the end of the afternoon, almost everything was working | ||
| 156 | as intended. | ||
| 157 | |||
| 158 | ## My experience so far | ||
| 159 | |||
| 160 | So far everything is working smoothly. Once in a while I notice | ||
| 161 | a minor mistake I made during the setup and I fix it - for example, | ||
| 162 | I have just noticed this morning that lighttpd's access log was | ||
| 163 | eating most of my storage, so I disabled it. But everything is now | ||
| 164 | up and running, and this page you are reading is served by my new | ||
| 165 | stack - unless you are reading it years after I published this | ||
| 166 | post and I have changed my setup again in the meantime. | ||
| 167 | |||
| 168 | The only real difference I noticed is that when I use `rsync` | ||
| 169 | to update my website, the whole process is much, much faster | ||
| 170 | - like 10x faster. I don't know if this is because the new | ||
| 171 | server has a much faster hard drive or because OpenBSD's `rsync` | ||
| 172 | was much slower. In any case, it is a nice surprise! | ||
