Back in April, GitHub shared a staggering graph of their scaling challenges:

LLMs are producing code at an almost frightening rate, and if you use GitHub on a semi-frequent basis, you’ll know that it’s
down quite regularly these days as a result of the onslaught.
For my own personal work, rather than tolerate the GitHub instability, I’ve instead opted to self-host my own Forgejo instance in my basement
server rack.

This is yet another important step in reclaiming my own computing sovereignty. While the world is busy spraying gigatons of slop all over GitHub, I’m
taking back ownership of the code that’s always been mine. Growing in my craft means not just owning the work, but also building the tools and the
environment that the work gets produced in. I aspire to build the Hans Zimmer music studio of computing.

Running my own private code forge has been a joy, especially with “push to create repository” Forgejo feature turned on. This enables
any whimsical hairbrained idea to quickly become a git repository stashed for my own private creation. If I want to live a creative life, full of Big Magic, I have to start with the basics:
doing a huge volume of work. A private code forge is a great scratch-pad to sink ideas into.
If you’re looking for a sign to bring your code “back home”, either personally, or at your company, the graph above might be the right signal that it’s time to take a look at
self-hosted options. Forgejo is definitely worth a look!
The server rack continues to expand! In an effort to buy
hardware before the AI bubble continues to drive up computer hardware prices, I’ve added three more Minisforum UM690L
mini PCs to the basement rack (this time in black!).

I’ll be using this new batch of machines to separate a testing cluster from “production” infrastructure
that runs the stuff in the house (Home Assistant, Jellyfin, etc.)
I haven’t yet isolated the network switching / routing, but that’ll come at some point.
In the meantime, I’ll keep on cheering for the AI bubble to crash in hopes of computer hardware
returning back to earth.
One thing that’s still underrated in programming: Skipping a library dependency and
coding something small that you need directly. No over-generalized library, no unecessary abstractions, no library dependency hell – just
straight forward code that solves your specific problem in the most direct way possible.
To put a longer story on it: I’ve been working on provisioning VMs with cloud-init NoCloud for
the cloud orchestration platform I’m building. To bootstrap VM state from a fresh image, I need to expose a VFAT disk from the host hypervisor
to the guest with the VM’s metadata (Network setup, hostname, users, etc.). The disk image needs to be dynamically built during
VM provisioning time, and injected with the correct instance information inside the VFAT volume for the guest to read.
VM provisioning happens in Rust code, so there are so a few different ways I considered implementing this:
- Build up a directory on a local scratch temp dir with the instance metadata files, and shell out to
mkfs.vfat with something like std::process to turn the directory into a vfat volume.
- Use an existing Rust library like fatfs to write the instance metadata files into a new FAT filesystem
Both of these require taking on external program or library dependencies.
I went a different way instead. I made a single zero-dependency Rust function that builds up the FAT filesystem in memory, and writes out the bytes directly to a file on the host.
It’s a few hundred lines of code, most of which are comments and tests. I read an old Microsoft FAT specification, wrestled with the hackish oddities of Long Filename support, and got
something working in a few hours time.
What’s missing from this implementation? So much!
- Only supports a fixed number of FAT filesystem clusters
- Only supports fixed filesystem sector sizes
- Only supports a hard-coded root directory size
- Hardcoded filesystem label only (It has to be the string
cidata to work with cloud-init anyways!)
- No read support
- Basic FAT12 only (No larger files with FAT32)
- No general file write interface: Just supports writing the 4 metadata files we need and that’s it
- Immutable writes only, no updates / mutations.
But this is all I need (and will probably ever need!). If I ever start doing anything fancier and dynamic with FAT filesystems, I can re-evaluate.
Instead, I get no breaking API changes from upstream libraries, no CVEs to patch, no license changes or rug-pulls, and code that’s straight forward and easy to fix and debug directly. Why carry around the extra weight of more dependencies for such a tightly scoped problem? We’re only writing 4 small metadata files to the vfat disk image after all.
Was this the quickest way to solve the problem? Probably not! Slapping in another dependency via cargo add and gluing some more APIs together would have probably gotten the problem “out of the way” faster from the start. But the initial expediency shouldn’t overshadow the benefits of building something tidy, compact, and definitionally simple like this.
I want less duct tape and glue in my programs. I want less moving pieces and maintenance. I want code that’s mine. I want systems that are load bearing and ready for production. I want more functionality, with less dependency.