SPARKSTHINKTANK
Lab note · Home Lab Platform

A homelab operated like production.

Two MicroK8s clusters and a NAS. Git is the source of truth. Images never leave the LAN. The same delivery path that ships this site also ships everything else.

The problem

Most homelabs are a pile of compose files and SSH. That works until you have two clusters, persistent storage, and a real release cadence. Then you need what production needs: GitOps, an on-prem registry, runners that can see the LAN, and a place to look when something pages.

The shape

The devops cluster is the control plane. The home-lab cluster is where workloads run. A NAS sits beside both and exports NFS so persistent volumes survive a node, a reboot, or a rebuild. Argo CD on devops deploys to both.

DevOps cluster

MicroK8s control plane. Argo CD, Zot, MinIO, ARC runners, Prometheus, Grafana.

Home-lab cluster

MicroK8s workloads. Apps pull images from Zot and sync from the same Git repo.

NAS

NFS for both clusters. Registry data, object store, GitOps state, app volumes, backups.

The stack

Argo CD

App-of-apps. A commit in Git is the deploy. Both clusters, one repo.

Zot

On-prem OCI registry for images and Helm charts. Pulls stay on the LAN.

MinIO

On-prem S3-compatible object storage. App blobs stay off the public cloud.

ARC runners

GitHub Actions on the cluster. Builds can reach Zot, NFS, and LAN DNS.

Prometheus

Control-plane metrics, including Argo CD, on the devops cluster.

Grafana

Dashboards on the devops cluster. The same names the DNS repo publishes.

Delivery

Merge to main. An ARC runner on the devops cluster builds the image, packages the chart, and pushes both to Zot. CI then bumps the version in the Argo CD repo. Argo CD syncs. No long-lived kubeconfigs in GitHub cloud; the runner already lives next to the clusters.

GitHub ──► ARC runners ──► Zot │ ▼ Argo CD ──┬─► DevOps cluster └─► Home-lab cluster ▲ NAS (NFS) ───────────────────────┘

Why this shape

Split control plane from workloads so a noisy app cannot take down GitOps. Keep the registry and object store on-prem so a Docker Hub or S3 outage is a non-event. Put runners on the LAN so CI can talk to Pi-hole, the NAS, and private ingress. Watch it with Prometheus and Grafana because “it works on my cluster” is not an operating model.

← Projects