GitOps
Nothing gets kubectl apply’d by hand. ArgoCD watches git and makes the cluster match it.
Two repos
homelab_k3sis the how: cluster bootstrap and the ArgoCD root applications.homelab_kube-appsis the what: every manifest that runs on the cluster.
Renovate opens most of the pull requests in homelab_kube-apps. Splitting the repos keeps those version bumps away from the deployment wiring.
App of apps
Three root applications point ArgoCD at the different layers:
root_application_core.yaml # core components (Helm charts)
root_application_prod.yaml # ApplicationSet over apps/*/overlays/prod
root_application_dev.yaml # ApplicationSet over apps/*/overlays/dev
The prod and dev roots are ApplicationSets with a git directory generator. Adding an app means adding a folder and committing it. No wiring changes are needed.
App layout
Every app uses the same Kustomize structure:
apps/<app>/
├── base/ # deployment, service, pvc
└── overlays/
├── prod/ # patches, ingressroute, vaultsecret
└── dev/ # optional
Apps started out as Helm charts I wrote myself. For apps I own, Kustomize turned out simpler: plain YAML, no templating to debug, and Renovate can bump image tags directly. I wrote about the move here.
Core components
Platform pieces are thin wrapper charts around upstream Helm charts, with my values next to them:
| Component | Purpose |
|---|---|
| Traefik | Ingress |
| cert-manager | Let’s Encrypt certificates via Cloudflare DNS |
| Longhorn | Replicated block storage |
| CloudNative-PG | PostgreSQL operator |
| Vault Secrets Operator | Syncs secrets from OpenBao |
| Prometheus | In-cluster metrics, federated outward |
| Alloy | Pod and node logs to Loki |
| Gitea runners | CI runners inside the cluster |
| Reloader, Descheduler | Restart on config change, rebalance pods |
The homelab page reads this list straight from the repo every time the site is built.
Renovate
Renovate runs on a schedule against every infrastructure repo. Out of the box it tracks Helm charts, container images and OpenTofu providers. Custom regex managers also track binaries that Ansible installs, like Gitea, Loki, Garage and even PaperMC builds for the Minecraft server. Minor and patch updates merge automatically, and major versions wait for review.