aboutsummaryrefslogtreecommitdiff
path: root/src/blog
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2026-09-05 14:33:52 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2026-09-05 14:33:52 +0200
commit014f13ada8339ba990909f3b9810c29394795aa5 (patch)
treed95484c579e83102382449b98399c43bce96f082 /src/blog
parentf013207d3db211a0ef4796d50218849c5bc9765f (diff)
downloadsebastiano.tronto.net-master.tar.gz
sebastiano.tronto.net-master.zip
New blog postHEADmaster
Diffstat (limited to 'src/blog')
-rw-r--r--src/blog/2026-09-05-cgit/cgit.md141
1 files changed, 141 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..53c00bd
--- /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 the
91next post.
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.

Generated with cgit - Back to sebastiano.tronto.net