Homelab GitOps starter¶
A platform, not a distro and not an app store.
You get a Kubernetes cluster whose day-2 life is Git: Argo CD watches this repository, syncs Applications in waves, and you add workloads later. The cluster still depends on things outside Kubernetes — DNS, a CA, object storage, maybe NFS. Those are documented here so they are not a surprise.
GitHub: jslay88/homelab-gitops-starter
Who this is for¶
Someone standing up a homelab cluster (Talos VMs on Unraid or Proxmox) who wants the same kind of platform that a long-lived GitOps lab uses: MetalLB, ingress, cert-manager, Longhorn, sealed-secrets, optional Postgres operator and backups.
It is not a dump of someone else's live lab. There are no real IPs, no SealedSecrets, and no workload charts.
How to use it¶
- Fill in the inventory on paper or in a notes file.
- Use this template → new repo, private. Do not fork: a fork of a public repo stays public and stays linked. Replace
YOUR_GITHUB,CHANGEME, andexample.cominmaster-application.yamlandapplications/. Private Git: create the Argorepo-credsSecret before the App of Apps (bootstrap). Wave 2 only seals that Secret into Git later. - Read local DNS and Step-CA before you pick hostnames. The cluster cannot invent a LAN nameserver or a private CA.
- Pick addresses (reserved CP / worker / VIP blocks; cluster name
homelab). Three control planes plus a Talos API VIP at.20sokubectlhas one IP that survives a CP reboot. Build Talos under~/talos/homelabon Unraid or Proxmox, then bootstrap Argo CD. - Walk waves 0–9, then observability (wave 10) or delete
applications/kube-prometheus-stack.yaml. Delete Application files you do not want. Stop at each Validation block — the next wave will not paper over a failed check. Upstream docs for every pin: versions. - First app: one whoami Ingress + Step-CA cert so you know DNS and TLS work.
- Talos day-2 when you upgrade or add a node. Backups when MinIO exists. Chart bumps when you change a pin.
- An AI assistant can use
kubectlor a Kubernetes MCP server against this repo and the cluster. Git still owns apply.
What GitOps means here¶
helm install argocd (once)
│
▼
master-application.yaml ──► applications/*.yaml
│
▼
Helm charts + values/ manifests
After the first apply, you do not helm upgrade platform charts by hand. You change Git; Argo syncs.
We use App of Apps (one YAML file per Application), not ApplicationSet. Homelab platform apps are few and different from each other — Helm-only, raw manifests, extra ignoreDifferences. A shared generator fights that.
Two Applications are chart + raw manifests in one object (MetalLB pools, StepClusterIssuer). The rest are chart-only or YAML-only. Breakdown: Application sources.
Two kinds of hostname¶
| Kind | Example | DNS | Certificate |
|---|---|---|---|
| LAN only | grafana.k8s.home.example.com |
Your BIND / router (DNS) | Step-CA |
| Public | app.k8s.example.com |
Public DNS | Let's Encrypt |
| Public, path only | argocd.example.com/api/webhook |
Public DNS | Let's Encrypt — UI stays on the LAN (wave 7) |
If you skip both BIND and Step-CA, you can still reach apps by IP or by /etc/hosts, with browser warnings. That is a worse lab.
UIs that already run on the LAN (NAS, router, a Pi) use the same Ingress and the same two cert paths. The backend is a Service plus an EndpointSlice, not a Pod.
Out of scope¶
Workloads. Identity products. Ad-blocking DNS as a cluster component (Pi-hole can sit in front of BIND later). A descheduler. Multi-instance Postgres HA. Cilium. Those are left out on purpose.
Docs wrong or a step that cannot work as written: Get help (open a GitHub issue). Changes to the public starter: Contributing.