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

Generated with cgit - Back to sebastiano.tronto.net