<- back

The Forgejo Runner

16.10.2026

While my current server runs nice and dandy, including a cool Forgejo instance and all... I began wondering - wouldn't it be cool to check out what all those neat GitHub/Forgejo/Gitea/GitLab Actions and other CI/CD tools can do? I mean, now that I have a blog post where I can simply put in new .html files and get a new blog, it'd be super nice if getting those to the actual web container would be as easy as possible.

Write page -> push page to Forgejo -> Some mystery action automatically builds a new image -> change version tag in Kubernetes deployment

And voila - eased deployment! Simple in theory....... and of course, not so simple in practice.

The first fun part was trying to install Forgejo Runner. Since I only had that one server and I like containerization, I began with a forgejo-runner container and a DIND container, which forgejo-runner would then call to create new containers to run jobs. This was a nightmare, to say the least. Frankly, I still don't quite get how it worked, but it did! The biggest of problems was file permissions - it turns out, because of my rootless docker setup, the data/ directory which the container was mounting was owned by 1000:1000, which in the container translated directly to 1:1 (root), so the container, which was running as 1000, could no longer open it. This alone took me quite a while to debug (shame on me, since I'm pretty sure 1000 translating to 1 is, like, a big part of rootless docker).

Nevertheless, I eventually got it working, but I was still worried about one little thing:

( will insert the actual error here later)

Oh, that's probably not a good thing. Thankfully, the 0.0.0.0 was from the perspective of the container, so on my host machine, this port was not open (though even if it was, it still wouldn't be publicly accessible). Still, the message that it would be a hard failure in the future did not instill much confidence in me, so I decided to go for option 2 - running Forgejo Runner as a binary on a new server altogether.

As the good systems administrator I am, I, of course, opted for the nice and secure(r) option - to run jobs, the Forgejo Runner would launch LXC containers that then run docker build and whatever else. Unfortunately, this did not go well with my decision to also test out AlmaLinux on this new server. The Forgejo Runner, for whatever reason, has hardcoded debian as the image of choice when launching containers. I did my best to overwrite this, but I could just not get it to try anything else other than the lxc-debian template. In the end, I said 'fuck it' and went with their advertised 'simple but unsecure' variant. I simply gave it the docker socket to the pass unto the job-running containers so they can access it for building and other needs. Finally, this worked. Thankfully, since the server is otherwise only accessible through :22 (with no password authentication), generally it is only vulnerable if the Forgejo instance itself gets exploited, but at that point I'd be more worried about the actual main server, not this lone Forgejo Runner runner.

Now, the pipeline... works! After adding my changes to git, tagging them and pushing, the Forgejo Runner automatically builds a container image with the new content, making it available to pulling. Still, I am a bit ashamed how LLM-heavy this was - I did more-or-less get an understanding on how to set this up without an LLM now, but doing it via plain old Googling would have probably taken *awhile*.