Hosting git repositories for personal projects

Published

# Contents

I have been self-hosting stuff for quite a while (in the perspective of my life at least), I started by running some code on a Raspberry Pi at the time the first one came out (probably late 2012). And after a while I have moved to having a bit more resources behind the services I run. Most of these services are projects that have been coded by me, and that for one reason or another doesn't make sense to open-source. So I need somewhere to host the code for this, all the while I have grown accustomed to just put things I am working on in git, so I don't have to worry much about loosing history, or accidentally deleting stuff.

# Github

I started by making repositories on Github for most of my projects. Some of them were public, and some of them were private, since I had a student discount. This worked fine, I don't remember too much about this time. But I do remember it feeling silly to send all my code and data to some third-party, when I didn't want the code to be public.

# Gitlab

At the time I had just gotten access to a VM on a decommissioned server running in a closet at my fathers office, with all the NAT-ing I wanted. With that much more resources, and having little other priorities, I installed Gitlab Omnibus onto a Debian system for the first time. I cannot remember exactly why I went for Gitlab, but I am guessing that was what people at the time were writing about on some subreddit where I lurked.

When started this Gitlab-instance, I started to make a distinction. I have been publishing things that I have felt could be useful for others on Github, and kept my personal projects on Gitlab. To be clear, both of these are personal projects. But when I use Github, I put at least some effort into having some documentation, and making the code somewhat extensible for use-cases other than my very spesific one.

When I started using Gitlab, and because that was where i really started, I have never really missed a feature. There were some things I realized I was missing when I started using it professionally, but not for personal projects. And while I have never really been a real user of Github, I haven't gotten used to any features there. This meant that I have always been really happy with Gitlab, and at some point I started to learn about docker. At which point I started using Gitlab CI, and ever since, I have been disappointed by all other automation solutions I have tried. Github Actions, woodpecker, Jenkins, Drone CI (See more in pipelines).

Even though I had grown very accustomed to the fantastic automation solution in Gitlab, I realized once I started running other services not written by me (like Nextcloud), that it really uses a lot of resources idling. Over time the feeling that this was a pure waste grew on me, to the point where I started trying to tweak it a lot, and even tried to run it in docker with some autoscaling-features. None of these really helped. For my personal projects I also used a extremely limited set of the features it offers. I used the repositories, the registry, Gitlab CI and the wiki feature.

# Gitea

So my search began for something more lightweight, it was quite hard to move from the experienced nicities of Gitlab to something like Savannah. In the end, I went for Gitea. It had every nice feature of Gitlab that I needed, apart from the Gitlab CI. Which I knew I couldn't get elsewhere anyway.

Apart from being a lot of work, since I couldn't do any batch-imports, the transition was quite seamless. The wikis I had was replaced by markdown-files I could work with in VimWiki or Obsidian. Which meant the only thing that I really needed to move was the git repositories themselves.

# Forgejo

Later I moved to Forgejo It was a complete drop-in replacement for me, and I have been using that for the last year. I moved because of the Gitea licensing, but it was the same software really when I moved. For the first time, the versioning scheme diverged this April, so it will be interesting to see what the future holds there. Although, unless something really new-thinking comes along. I don't have use for any new features that I don't already have. Unless I want to use it for more people than myself that is.

# Git

Lately, I have encountered a few instances where things have gone a bit wrong in my docker clusters (k3s). I have started to realize that this is mostly a lot of additional infrastructure and complexity that I don't have the time or energy to manage for my homelab "production"-services any more.

I have almost stopped using pipelines for building docker images now, and instead rely on simple bash-scripts and ansible-playbooks. In one way, this is more complex, because it is on me. But in the end, it makes for less cogs that needs to be well-oiled.

The reason I have stopped using pipelines, is so I don't need to have a large git solution. For most of my repos now, I have a LXC-container, with a single user, and SSH-access. on this user, I run the very simple:

mkdir <repository>
cd <repository>
git init --bare

And this serves as my git repo. I have a file-system mounted for these repos, which is a ZFS-volume. It replicates to another server, but does not have any automatic failover. Because automatic failover creates a lot of complexity. It also has daily backups which are encrypted and sent to a cloud storage provider. This means I have a lot less things that can go wrong in the infrastructure of the git server. It is simply a linux-box, with a normal filesystem. This has been quite freeing, as unless there has been a major filesystem corruption, I don't need _both the VM/LXC, Docker engine, kubernetes agent, longhorn agent AND the git service to be able to start. Only the first step can go wrong, and it quite rarely does.

As fun as it is to manage a full-blown enterprise infrastructure in a home-lab, transitioning from being a student means less time to faff around on the projects that are just maintenance, with little opportunity for acquiring new knowledge.

It is likely that this will be my approach for the foreseeable future, it is quite simple, limited security vulnerabilities, easy to backup and restore. All in all, a reasonably good solution for homelabbing.

# Pipelines

The journey for finding a replacement for Gitlab CI, has not yet concluded. I am quite likely going to end up mostly using shell scripts, which I manually run when I need them on a build-server. Currently I still have a few pipelines which build docker-images in Drone CI. But it feels quite unnecessary, and just adding extra steps to everything I do.

As mentioned before, this story would be quite different if I was not the only one working on these things, or if any of my software was being built and used by anyone else. But that is not the case, so I can deal with forgetting to run cargo fmt && cargo test before committing, or simply enforcing pre-commit-hooks on myself.

Just for a quick mention of other tools: I have tried woodpecker, but it didn't really fulfill the CD requirements I had. I have been planning to try the new Gitea Actions, but I have not gotten around to it yet. It is supposed to be quite similar to Github Actions, which is not what I have the best experiences with. But I have never really studied either of them.

# A simpler infrastructure

As a summary of my journey; I have been a fan of large infrastructure, but I am slowly realizing that it has diminishing returns compared to the invested time. Especially considering that most of this infrastructure is for me and only myself.

Gitlab is a fantastic piece of software, I have used it extensively professionally, and I have no doubts that with a team of 10+ people, the features that exist there can significantly improve the workflows and collaboration efforts. For a homelab with one user and contributor however, it is very unlikely to be worth both the upkeep and resource usage.

Software like Gitea and Forgejo definitely has their place, I believe they are great if you use the additional features extensively. Such as the built-in docker repository, wikis, issues and now maybe the Actions.

For me, I will continue using Makefiles and Bash-scripts as entry-points for my "pipelines". And running them on my build-server by pressing enter, instead of doing something in a web-ui. As that requires the least effort to maintain, and keep up to date.