Homelab as Code
Built in five layers
Start at the hardware and add one layer at a time. Every layer is declared in code.
One toolbox, nothing to install
Every layer is driven by a single container image, so there's no toolchain to set up locally. State lives in a Cloudflare R2 bucket; the cluster runs the rest.
The runner image
In-cluster operators
From a commit to a running app
The only step I run by hand is the commit. The rest happens on its own.
01 A commit lands on main
Renovate opens the PR, CI lints and validates the manifests, and after it merges the repo is the source of truth for the whole lab.
02 Argo CD notices it's OutOfSync
Argo CD watches the repo and compares what Git declares against what's actually running. The new commit means the cluster no longer matches Git.
03 An ApplicationSet expands the tree
An ApplicationSet turns the directory layout under kubernetes/cluster/active into Argo CD applications. Add a folder, get an app.
04 Helm + Kustomize render the manifests
Kustomize renders the charts with --enable-helm and hands Argo CD the exact objects to apply.
05 Secrets come from outside Git
The External Secrets Operator pulls values from Bitwarden Secrets Manager when the objects apply. One bootstrap token unlocks the rest, so no secret ever lands in Git.
06 Synced and healthy
Argo CD applies the changes, prunes anything no longer in Git, and reports Synced and Healthy. The cluster matches the commit now, and it stays that way.
What's actually running
Every one of these is declared in the repo and reconciled by Argo CD.
Built and documented in the open
I run this homelab to host my own services and to keep my DevOps and platform engineering skills sharp, and I write it all down as I go.
Task