GitHub Pivoted. So Did I. — Part 15 of Building a Resilient Home Server Series
Back in Part 11, I wrote this:
"If GitHub ever 'goes stupid' — account suspension, policy changes, acquisition drama — all my code is sitting on hardware I own, with backups being replicated by Syncthing. GitHub becomes the mirror, not the source of truth."
I added a spoiler alert to that line recently. There's a reason.
If you missed it, Phase 3: Profit — The GitHub Story covers what happened in detail. Short version: GitHub announced they'd be using interaction data from Copilot Free, Pro, and Pro+ users to train AI models starting April 24th — opt-out, not opt-in — reversing a position their own staff had stated clearly just four months earlier. Same week Microsoft published a "we hear you" post about Windows 11. One hand soothes, the other grabs your code.
I went to figure out what leaving would actually take.
Turns Out I'd Already Done Most of It
This is the part that surprised me.
Part 11 covers the Gitea setup in full — self-hosted Git running on nixos2, with push mirroring to GitHub already configured. The whole point of that setup was that Gitea is the source of truth and GitHub is just a mirror. I built that for reliability reasons, not because I saw this coming.
Part 9 and Part 12 cover the backup chain — Restic snapshots Gitea nightly, Syncthing replicates those to the Mac, iCloud picks it up from there. Three tiers. Already running. Didn't add any of it for this.
The failover story from Part 11 is also real — nixos (the main server) has the Gitea config sitting there with
enable = false. If nixos2 ever goes sideways, it's a restore and a flag flip. The architecture was designed for that.Basically I went to assess the damage and found out past me had already handled it. Accidentally, months ago, for completely unrelated reasons.
What I Actually Did
The backend was done. The frontend needed some work.
Swapped the mirror destination. Same process as the GitHub mirror in Part 11 — Gitea repo settings, add push mirror, Codeberg personal access token, URL pointing at
codeberg.org/ppb1701/reponame. Removed the GitHub mirror. Codeberg is now where the code goes. Gitea doesn't care who it's pushing to, it just pushes.
Gutted GitHub. Each repo is now an empty shell with a forwarding README pointing to Codeberg. The account stays because I use it for a couple of OAuth logins I'm not rebuilding a whole tailnet to change. But the code left.
Left private repos alone. Codeberg has limits on private repos and more importantly they're a third party. The whole point of private repos is keeping them off third party platforms. Gitea handles them, Restic backs them up, Syncthing moves those backups to the Mac and iCloud handles the offsite leg. No third party ever touches the private stuff. That's the right architecture and it was already there.
Fixed a small permissions gap. While reviewing the backup config I noticed the Gitea backup job was missing the postStart chmod/chgrp block that all the other backup jobs have. Cosmetically fine because the private-configs job runs later and fixes the whole directory anyway, but technically Syncthing could have silently skipped new Gitea snapshot files if it ran first. Fixed on both servers.
What's Still GitHub's Job
GitHub isn't gone, it's just a billboard now.
- Virtual billboard — old links from blog posts and search results hit the forwarding README and land on Codeberg. 100 million GitHub users browse repos. Staying visible there costs nothing.
- OAuth — a couple of logins I'm not rebuilding a whole tailnet to change
The code moved. The account stayed.
The Accidental CYA
The thing that keeps getting me about this whole exercise is how much of it was already done.
I didn't build the Gitea push mirror because I thought Microsoft would eventually use my code to train AI models. I built it because having a single point of failure for my repos felt wrong. I didn't set up the Restic/Syncthing/iCloud chain because I was planning to cut GitHub loose. I set it up because I wanted offsite backups.
But when the policy changed and I went to assess what leaving would take — it was mostly done. Past me had accidentally covered the exit.
Bitwarden doubled their price. I'd already left. GitHub changed their data policy. I'd already mostly left. When a platform does something you don't like, you're not stuck. That's the whole point.
The full configs are on Codeberg: nixos and nixos2. The ISO can be gotten here. If you're following along on Mastodon: @ppb1701@ppb.social