Private setup for GitHub Actions runners

GHA is my private setup for running GitHub Actions runners for multiple repositories on one VDS. It handles runner registration, a shared job queue and resource limits, letting me run CI jobs on my own server while keeping the workflows in GitHub.

Private setup for GitHub Actions runners - active queue
Private setup for GitHub Actions runners - active queue

About Private setup for GitHub Actions runners

The motivation was a GitHub Actions bill. Very inspiring stuff.

I use Actions heavily for builds, tests and other checks across my projects. Those jobs add up, and running them on my own VDS made more sense for my workload. Then came the slightly less exciting part: managing all those runners without letting several repositories overwhelm the same machine.

For personal repositories, each repo gets its own runner registration and service. They share a global queue, so jobs run one at a time. Several repositories can have work waiting, but they have to take turns using the server. There’s also an organisation mode where one runner can serve repositories within the same GitHub organisation.

CI runs under a dedicated user with rootless Docker and CPU and memory limits. My production applications keep using their existing Docker setup. That separation matters when the machine doing your builds also has actual websites to run.

The rest is mostly making the routine work less annoying. There are scripts for adding runners individually or in bulk, checking their status, reading logs, inspecting the queue and removing runners when they’re no longer needed. There are also helpers for cleaning up CI Docker data and manually unlocking the queue if an interrupted job leaves it stuck.

It’s all Bash, built around the way I use my own server. A useful little infrastructure project that started because I wanted to keep running my checks without repeatedly checking how much the checks were costing me.

Release history

Version 0.1.2