Geet Web Service

  • gws, docker, git
  • 8
  • 3
  • finished

With recent news about Gitea being took over by the newly funded for-profit company, Gitea Ltd, which resulted with Forgejo fork, I decided that I’m sick of “constant” drama around Gitea (which itself is a fork of Gogs) and have spent January creating totally personal Git web server. Please welcome GWS: Geet Web Service.

At its core GWS is a Docker image which integrates Gitolite as Git backend and Cgit as a frontend. At this point Docker is a boring technology, so to keep things interesting I added some goodies which I was using with Gitea:

  • full HTTP access (anonymous or authenticated pulling and authenticated pushing);
  • HTTP users management (separate from the ordinary SSH);
  • webhook;
  • migration helpers;
  • allowing mixing of user code and GWS code for custom Git hooks, Gitolite triggers and SSH commands, with focus on painless updates1
  • easy setup for full Git server administration via a special gitolite-admin repository2.

These are the core features which I expect from my Git web server.

Internal Organs

What’s inside GWS?

First of all: Gitolite, which is incredible, yet a little forgotten Git backend. Its modus operandi bases entirely on SSH and Git hooks and Gitolite acts as an orchestrator for them. I am amazed how powerful is its approach for managing a Git server. With a little bit of imagination you can do almost anything without hacking your way around. Some people call it “basic” or “simple”, but it’s anything but basic. It has near endless possibilities to configure the Git server.

As you see, I am in love with Gitolite. gitolite.com is my homepage now and I have added its author’s e-mail to my contact book, but without reciprocity ;). When I started writing GWS, I was a complete Gitolite ignorant, only liking a fact that it seemed command-line focused. After a month spent bending it to my will, rewriting some GWS features twice because I found a better way of doing things, I must say that it’s one of the most pleasant and comprehensive progams that I’ve used. And its written in cryptic Perl which I somehow understand. Incredible!

On the other end of spectrum is CGit, which is fast and powerful Git web frontend, with caching. It looks feels a little dated by today’s standards, but I’ll work on it next. Making it mobile-friendly is my goal.

I admit, I didn’t give a lot of love for CGit. It’s also my least-liked part of GWS. I’m not particularily attached to it, but I’ve found no other frontend which integrates with Gitolite so nicely.

For me, the backend guy, the worst part of CGit is that it is a a CGI script which spawns a new process for each request. It should suck for 200k different requests made by Amazonbot, but CGit somehow handles them without a sweat. I’m going to stick with it though, at least for now, and see how far can I go with its CSS.

How’s It Been So Far?

We are here because at some point I evaluated my use of Gitea and concluded that I use maybe 30-40% of its features. Right now I’m dogfooding myself with GWS and I’m using exactly 100% of its features.

The migration went surprisingly smooth. Everything worked out-of-a-box, even web hooks, which I thought were the most fragile, because JSON sent by GWS’ webhook is “less complete” than the one sent by Gitea. Even though I was preparing both GWS and myself for this moment for a month, I always thought that there will be some hiccups. There were none, at least none related to GWS. I am quite proud of it, because a month of planning and hard work payed for themselves. Likely for the first time in my engineering career3. :)

If you’re interested about the mistakes, there were two of them. First one was about migrating the wrong backup of repositories. It involved docker-compose not catching a local bind-mount, to which I switched in December, so IT WASN’T MY FAULT, was it?. It seems that I only thought that my Gitea container was using that bind-mount, but it continued to use the old volume. I think I forgot to do docker-compose down at some point, so it didn’t prune the old volume, but I might be wrong. I won’t be doing a post-mortem of this.

For a second I thought that I have lost a month worth of changes across all of my repos (82).

Second one was a simple memory issue. I forgot to chown migrated repositories to a different user used by GWS.

Hows’ been the usage? Delightful, but I’m biased. :)

GWS is ultra-lightweight and ultra-fast compared to Gitea, which was fast by itself. The speed of pushes and pulls is comparable to the speed of local operations, and by local I mean same-HDD-local. git push and git pull take ~190 ms and simply reaching my git server takes ~50 ms. Not bad, not bad.

I’m going to spend next 2-3 days polishing the configuration of my server. After all, all repositories have default descriptions. Then I think I’m going to finally give some love to CGit’s CSS or some other things which are on my TODO list. Or maybe I’ll finally finish rewriting Zet’s modules to the new API.


  1. I am realistic that there will be bugs and/or new ideas. Software updating is a part of our lives and I like them to be stress-free. 

  2. For security reasons it’s not enabled by default. 

  3. Did I tell you how I’ve been changing a radiator in my daughter’s room? :)