↓Skip to main content
homelab

Four nodes.
One repo.

A self-hosted Kubernetes cluster that runs everything I run at home — fully declarative, GitOps-reconciled, LAN-first. If it isn't in git, it isn't real.

self-hosted·gitops·zero cloud dependency
4nodes
2gpus
38workloads
1git repo
topology

The shape of it

One commit travels the whole path; anything that drifts gets reverted.

k3s · 4 nodesanchorcp·edge·amd64braingpu·arm64sidekickgpu·arm64tinkererarm·debiangit pushone repo · mainArgoCDpoll · sync · healbrowsers @ homevia Traefik + TLSNASnfs · state

git push → reconcile → self-heal — everything behind one router

gitops

How a change lands

The cluster is a rendering of the repo. There is no other way in.

01

Commit

Manifests, routes and policies are plain YAML — reviewed like any code.

02

Push

One push to main of a single repo. That's the whole deploy button.

03

Sync

ArgoCD notices within minutes and reconciles the desired state onto the cluster.

04

Self-heal

Hand-applied drift is reverted automatically. The repo always wins.

stack

What the cluster runs on

Boring, proven open source — chosen to be maintainable at home scale.

k3s

The lightweight Kubernetes distro. Four heterogeneous nodes — x86 and a fleet of ARM machines — one control plane.

orchestration
ArgoCD

App-of-apps GitOps. Each application is one directory in one repo; new directories become new apps automatically.

delivery
Traefik

The sole ingress at the edge, with cert-manager issuing wildcard TLS behind the router. Nothing is exposed to the internet.

edge
NFS + CSI

State lives on a NAS via a CSI driver — Retain policy, per-PVC subdirs, SSD class for the latency-sensitive databases.

storage
Prometheus + Grafana

Metrics, dashboards and the alert rules that actually wake me up. Push metrics included for one-shot jobs.

observability
Beszel + Kuma

Light host monitoring with SSH dial-back agents, plus uptime probes and a status page for the whole fleet.

observability
Local AI

GPU nodes serve open models for inference and embeddings — private AI that never leaves the house.

ml
DNS + backups

A local resolver splits the wildcard domain; git itself is the backup format for the things that matter.

plumbing

On top of the stack, ~30 self-hosted services run as plain directories in the repo — no cloud subscriptions, no vendor lock-in, nothing that phones home.

fleet

Meet the nodes

Four machines of very different sizes, scheduled as one.

anchor

Control plane and edge. The dependable x86 workstation that carries the router duties, the DNS and the ingress.

amd64ubuntu ltscp + edge
brain

The NVIDIA DGX Spark with the modern GPU. Tainted and quiet — only inference workloads that ask for it get scheduled here.

arm64dgx sparkinference
sidekick

An NVIDIA Jetson with spare GPU cycles. Untainted, so it catches general workloads whenever it's idle.

arm64gputegra
tinkerer

A Raspberry Pi doing genuinely useful work. Light services only — RAM is the currency here.

arm64debianlight
network & storage

Under the hood

The router and the disks the whole cluster leans on.

UniFi Dream Router

The network itself is UniFi. The UDR runs the LAN and hands DNS upstream to AdGuard Home, which serves the *.lan wildcard — every app gets a name without touching the internet. A small syncer polls live UniFi clients and keeps per-device DNS records current, so even DHCP leases become GitOps-adjacent.

The NAS

Every persistent byte in the cluster lives on a self-built NAS — all PVCs served over NFS via a CSI driver with Retain policy, an SSD class for latency-sensitive databases, and an IPMI-scheduled backup drive that wakes only when it's needed.

Boring, on purpose.

Every change is a commit. Drift is reverted within minutes. The console is for looking, SSH is for emergencies, and the cloud bill stays at zero.