Homelab Kubernetes: MicroK8s + ArgoCD on a single box
A pragmatic single-node Kubernetes setup for personal projects: MicroK8s for the runtime, ArgoCD for GitOps, Cloudflare Tunnel for ingress, no cloud bill.
Personal Kubernetes that's actually fun to operate. Single 32 GB box, MicroK8s as the runtime, ArgoCD for GitOps, Cloudflare Tunnel for ingress so I don't open ports on my home network. Has been running since late 2025 with the only manual intervention being kernel updates.
Why MicroK8s
Three constraints made it the only sensible pick:
- Single-node for cost and noise — k3s and MicroK8s both fit. k3s is slimmer; MicroK8s ships with batteries (ingress-nginx, MetalLB, observability stack via add-ons).
- Add-on philosophy —
microk8s enable argocdis one command, vs hand-rolling a k3s ArgoCD install. Saves the early-stage friction. - Snap-managed updates — boring infrastructure should auto-update. MicroK8s does; k3s with k3sup is more manual.
Architecture
┌──────────────────────────────────────────────┐
│ Single host (Ubuntu LTS, 32 GB) │
│ │
│ ┌────────────────────────────────────────┐ │
│ │ MicroK8s │ │
│ │ ├── ArgoCD (GitOps controller) │ │
│ │ ├── ingress-nginx (north-south) │ │
│ │ ├── cert-manager (Let's Encrypt) │ │
│ │ ├── External Secrets (HashiCorp Vault)│ │
│ │ └── Observability │ │
│ │ ├── Prometheus + Grafana │ │
│ │ └── Loki + Promtail │ │
│ └────────────────────────────────────────┘ │
│ ▲ │
│ │ encrypted tunnel │
│ ▼ │
└─────[Cloudflare Tunnel]──────────────────────┘
│
▼
Public internet
No public ports on the home router; all ingress arrives through cloudflared over an outbound mTLS connection to Cloudflare's edge.
GitOps loop
Everything in ~/Repo/homelab-infra:
argocd/applications/*.yaml— oneApplicationper workload.argocd/applicationsets/*.yaml— templated apps (e.g., per-environment overlays).clusters/homelab/values/*.yaml— Helm values per workload, env-specific.
ArgoCD watches the repo every 3 minutes. Commit pushed -> ArgoCD reconciles within ~3 minutes. The dashboard at https://argocd.homelab.thulanimaseko.com shows sync status and a manual sync button for when I want it faster.
What runs on it
Five workloads as of writing:
| Workload | Purpose |
|---|---|
| Vault | Secret backend for the cluster + dev work |
| HomeAssistant | Lights, climate, observability |
| n8n | Workflow automation (RSS scraping, scheduled jobs) |
| Postgres | Shared DB for the above |
What I learned
The biggest unlock was treating it like a real cluster: helm charts, env-specific values, ArgoCD Application syncing — not a pile of kubectl apply scripts. The discipline scales: when I bring up a second cluster (planned: EKS for paid work), the GitOps repo just gets a new clusters/eks-prod/ directory and the rest is identical.
See also
- Repo
- /answers/argocd-vs-flux-2026 — why ArgoCD and not Flux