Infrastructure-as-code for my homelab Kubernetes cluster, managed with Flux CD GitOps.
┌─────────────────────────────────────────────────────────────────────────────┐
│ 🏠 Rangoon Pulse Homelab │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 🌐 LAN │◄───────►│ ☁️ Cloud │◄───────►│ 📱 Tailscale │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ └────────────────────────┼────────────────────────┘ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ 🔀 Ingress-Nginx │ │
│ │ 10.0.0.231 (MetalLB) │ │
│ └───────────┬──────────────┘ │
│ │ │
│ ┌─────────────────┴─────────────────┐ │
│ ▼ ▼ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ 🖥️ Primary Node │ │ 🥧 Raspberry Pi │ │
│ │ talos-7nf-osf │ │ talos-uua-g6r │ │
│ │ i5-8400T · 32GB · │ │ ARM64 · 8GB │ │
│ │ NVMe · Intel iGPU │ │ (Raspberry Pi) │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
| Feature | Description |
|---|---|
| GitOps-First | Everything reconciles via Flux — Kustomization + HelmRelease |
| Unified Access | Single ingress VIP (10.0.0.231) for LAN + Tailscale clients |
| Smart Storage | NAS-backed PVCs by default; local-path for DBs & hot caches |
| Auto Tuning | Resource Advisor CronJobs generate safe, budgeted resource PRs |
| Node Pinning | Userland apps pinned to primary node; ARM allowlist for Pi |
| SOPS Secrets | Age-encrypted secrets, decrypted by Flux at runtime |
| Node | Role | Arch | Specs | IP |
|---|---|---|---|---|
talos-7nf-osf |
Control Plane + Workloads | amd64 |
i5-8400T (6c/6t) · 32GB · NVMe · Intel iGPU | 10.0.0.197 |
talos-uua-g6r |
Utility Workloads | arm64 |
4 cores · 8GB (Raspberry Pi) | 10.0.0.38 |
Current cluster status: both nodes are functional and schedulable.
| Service | Description |
|---|---|
| AdGuard Home | Dual LAN DNS filtering & ad blocking |
| Glance | Dashboard & service hub |
| Uptime Kuma | Uptime monitoring |
| Grafana | Metrics & dashboards |
| Speedtest | Network speed testing |
| Resource Advisor | Automated resource tuning |
| Service | Description |
|---|---|
| Jellyfin | Media server with Intel iGPU transcoding |
| Immich | Photo & video backup |
| Seerr | Media request manager |
| Audiobookshelf | Audiobook & podcast server |
| Calibre | E-book library management |
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ autobrr │───►│ profilarr │───►│ prowlarr │
└─────────────┘ └─────────────┘ └──────┬──────┘
│
┌──────────┬──────────┬─────────────┼──────────┐
▼ ▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ sonarr │ │ radarr │ │ bazarr │ │ sabnzbd │ │transmission
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
Plus: tracerr for tracking automation metrics
Transmission can run direct or through a Gluetun sidecar, with the control toggle on controlpanel.khzaw.dev and the Gluetun WebUI at torrent-vpn.khzaw.dev.
Flaresolverr currently tracks alexfozor/flaresolverr:pr-1300 on the Raspberry Pi utility node.
| Service | Description |
|---|---|
| nodecast-tv | Live TV streaming |
| iSponsorBlockTV | SponsorBlock for TV clients |
| Tunarr | Channel scheduling |
| ErsatzTV | Custom TV channels |
| Service | Description |
|---|---|
| Actual Budget | Personal finance tracking |
| Vaultwarden | Password manager |
| ChartDB | Database schema diagrams |
| Obsidian LiveSync | Note sync via CouchDB |
| Anki Server | Flashcard sync |
| BookLore | E-book reader & manager |
.
├── apps/ # User-facing applications
│ ├── jellyfin/
│ ├── immich/
│ ├── glance/
│ └── ...
├── core/ # Core cluster components
│ └── ingress-nginx/
├── infrastructure/ # Infrastructure services
│ ├── cert-manager/
│ ├── external-dns/
│ ├── metallb/
│ ├── monitoring/
│ ├── resource-advisor/
│ ├── secrets/
│ ├── storage/
│ └── tailscale-operator/
├── flux/ # Flux GitOps configuration
│ ├── repositories/ # Helm repositories
│ └── kustomizations/ # App kustomizations
├── talos/ # Talos machine configuration
├── docs/ # Documentation & runbooks
└── scripts/ # Operational scripts
# Check Flux health
flux get kustomizations
flux get hr -A
# Reconcile a component
flux reconcile kustomization <name> --with-source
# Cluster triage
kubectl get pods -A
kubectl get events -A --sort-by=.lastTimestamp | tail -n 50
kubectl top nodes
kubectl top pods -A
# Talos node dashboard
talosctl -n 10.0.0.197 dashboard# Normal mode:
# 1) push in source repo (blog/mmcal)
# 2) image gets published
# 3) Flux image automation updates this repo on interval (6h)
# Fast path (deploy now)
make deploy-blog
make deploy-mmcalmake deploy-*forces image repository scan, image policy resolution, image update automation, source reconcile, and app kustomization reconcile.- Cloudflare cache policy should bypass HTML/update-critical routes (
/,index.html, service worker/manifest/feed paths) and cache static assets aggressively.
Warning
NFS PVCs failing? Check that the TrueNAS Tailscale app has "Accept Routes" disabled to avoid asymmetric routing issues.
See: docs/truenas-tailscale-accept-routes-caused-democratic-csi-outage.md
Note
The control panel image-updates view is best-effort. It compares stable semver tags directly, compares matching non-semver numeric tag families when the pattern is clear, and falls back to remote digest checks for floating tags like latest or next.
Grafana
Uptime Kuma
| Doc | Description |
|---|---|
ops-command-cheatsheet.md |
Full command reference |
adguard-dns-stack-overview.md |
Dual AdGuard DNS architecture |
gitops-change-timeline-dashboard.md |
Flux activity and reconcile timeline |
dns-access-path-dashboard.md |
DNS health and access surface |
resource-advisor-phase1-phase2.md |
Resource tuning automation |
node-capacity-dashboard.md |
Whole-host node CPU/RAM dashboard |
networking-current-state-and-simplification.md |
Network design |
pangolin-fit-analysis.md |
Where Pangolin could fit in the current access model |
secrets-inventory.md |
Secrets reference |
backup-plan.md |
Backup strategy |
| Domain | Purpose |
|---|---|
khzaw.dev |
Primary domain for all services |
*.khzaw.dev |
Service subdomains via external-dns |









