On this page
I already run a chunk of my own infrastructure. OpenTofu-managed services run at home, and a Dokploy swarm on a VPS handles anything that needs to stay reachable from the outside. The bigger reason was the Actions bill. GitHub Actions is free only on public repos, private repos get a monthly quota of minutes and then it’s billed per minute, and I deploy to dev and prod out of private repos constantly, so that quota was never going to last. On top of that I didn’t want one company holding the infrastructure my code and a client’s business data sit on, or terms of service that change whenever GitHub decides to change them and I find out from a changelog after the fact. Forgejo now runs my git hosting at git.nokopia.com.
Why a VPS instead of the homelab
Forgejo runs on the same VPS as the rest of my Dokploy swarm, not on the homelab box, on purpose. My home connection doesn’t have proper downtime mitigation yet, no UPS, no backup internet, so a power blip or an ISP outage takes the whole thing down with it. A git server that’s also my CI trigger needs to stay up more reliably than that. The homelab is great for services I don’t mind occasionally losing for an hour; it’s not where I wanted git hosting living yet.
The runner ran the VPS out of memory
CI took an afternoon, and memory was the reason.
The leader node, dokploy, is the primary VPS hosting the Dokploy control plane, Forgejo, Vaultwarden, and OpenBao. Running the Forgejo Actions runner on that same instance forced builds to compete for memory. When a CI workflow built a Node.js project, the compiler spiked RAM consumption and exhausted system memory. The instance triggered the Linux out-of-memory killer, bringing down the running services.
So the runner needed its own machine. I grabbed a Canada VPS because it was the cheapest one available that day, joined it to the swarm over WireGuard as a worker, and pointed Forgejo’s runner registration at it instead of the leader. What I actually wanted was a Singapore node, but nothing was in stock when I went looking, so I picked up a Jakarta VPS as a stopgap, closest region with availability. Once a Singapore VPS did open up, I added that too, planning to let the Canada and Jakarta ones lapse once their rental periods ran out rather than cancel early.
The screenshot below is from partway through that: the leader, the Canada worker, and the Jakarta worker, before Singapore joined.

Forgejo and its database stay pinned to the leader. The runner gets scheduled onto whichever worker has room, so the build that OOM’d the leader now runs somewhere that isn’t also holding my password manager and secrets store.
Where things stand now
Private repositories now live on git.nokopia.com by default. GitHub remains useful for public open-source code where discoverability and community pull requests matter. None of the privacy or compute concerns apply to repositories intended to be public.
To make sure I don’t lose my data, since I’m the one taking full responsibility for it now instead of GitHub, Dokploy runs periodic backups of the whole setup out to Backblaze B2, Forgejo’s database included. Losing that instance doesn’t mean losing the repos on it.
Between the VPS hosting Forgejo, the worker nodes, and Backblaze B2 storage, the setup costs slightly more in raw hosting fees than GitHub’s free tier. In return, compute costs remain predictable regardless of build volume, and the core development infrastructure runs on hardware I own.
Comments
Replies from the fediverse to @yuris@fedi.yuris.dev's post about this article.
No replies yet — open the post above from any Mastodon or fediverse app, reply to it, and your reply will appear here.