- YAML 84.7%
- Python 7.2%
- MARKDOWN 5.5%
- SHELL 1.4%
- JSON5 0.8%
- Other 0.2%
| .claude | ||
| .github | ||
| .playwright-mcp | ||
| .taskfiles | ||
| .vscode | ||
| bootstrap | ||
| docs | ||
| kubernetes | ||
| scripts | ||
| secrets | ||
| talos | ||
| templates | ||
| test-results | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .mise.toml | ||
| .renovaterc.json5 | ||
| .shellcheckrc | ||
| .sops.yaml | ||
| dashboard | ||
| get | ||
| INFRASTRUCTURE.md | ||
| LICENSE | ||
| makejinja.toml | ||
| README.md | ||
| Taskfile.yaml | ||
🏠 homeops
A single-node, GitOps-managed Kubernetes homelab - running on Talos, reconciled by Flux, and entirely declared in this repo.
📡 At a glance
Cluster home-cluster · single-node Talos Linux
Reconciler Flux CD · watches main, auto-applies on push
CNI Cilium · with LBIPAM + Gateway API
Storage OpenEBS + NFS-CSI · hostpath for state, TrueNAS for media
Backups VolSync → MinIO · restic, daily, off-cluster
Secrets SOPS + age · encrypted at rest, decrypted by Flux
Updates Renovate (auto) · PRs auto-merged with merge commits
| Namespace | Apps | Namespace | Apps | |
|---|---|---|---|---|
default |
31 | monitoring |
10 | |
media |
30 | databases |
6 | |
network |
6 | ai |
4 | |
kube-system |
4 | storage |
4 | |
cert-manager |
1 | Total | ~96 |
🏗️ Architecture
┌──────────────┐
iacob.co.uk │ Cloudflare │
┌─────────────────▶ │ Tunnel │
│ └──────┬───────┘
│ │ public
┌──────────┴──────────┐ ▼
│ User │ ╔═══════════════════╗
│ │ ║ envoy-external ║
└──────────┬──────────┘ ║ 192.168.1.8 ║
│ ╚═════════╤═════════╝
│ iacob.uk │
│ LAN / VPN │
▼ │
╔═══════════════════╗ │
║ envoy-internal ║ │
║ 192.168.1.7 ║ │
╚═════════╤═════════╝ │
│ │
└────────────┬────────────┘
▼
┌─────────────────────────────┐
│ Talos · home-cluster │
│ ~96 apps / 10 ns │
└─────────────┬───────────────┘
│ 10G NFS
▼
┌──────────────────────┐
│ TrueNAS │
│ media · backups │
└──────────────────────┘
LAN clients resolve
*.iacob.ukto192.168.1.7via AdGuard split DNS; public*.iacob.co.ukis served via Cloudflare Tunnel (no inbound ports open).
🖥️ Hardware
| Host | Model | CPU | RAM | Role |
|---|---|---|---|---|
| dl360 | HP ProLiant DL360 Gen9 | 48 vCPU | 252 GiB | Compute · K8s VM, AdGuard, Home Assistant, WireGuard |
| dl380 | HP ProLiant DL380 Gen9 | 40 vCPU | 157 GiB | Storage · TrueNAS, AdGuard secondary |
| Total | 88 vCPU | 409 GiB |
Network backbone: 2.5G LAN + dedicated 10G P2P between K8s node and TrueNAS for NFS traffic.
🧱 The Stack
|
Platform
|
Networking
|
Storage & Data
|
📦 Applications
Inventory derived from
kubernetes/apps/. Click a section to expand.
🎬 Media · 30 apps - *arr stack, streaming, transcoding, surveillance
Plex · Jellyfin · ErsatzTV · Tautulli · Sonarr · Sonarr-LowQ · Radarr · Radarr-LowQ · Readarr · Lidarr · Lidify · Calibre-Web · LazyLibrarian · Prowlarr · Bazarr · FlareSolverr · qBittorrent · SABnzbd · Overseerr · Recommendarr · Pulsarr · Wizarr · Tdarr · Recyclarr · Huntarr · Agregarr · Sharerr · Plexo · Frigate · Scrypted · Ring-MQTT
🛠️ Default · 31 apps - productivity, identity, utilities, hosted services
Authentik · Vaultwarden · Immich · Paperless · FileBrowser · SFTPGo · Zipline · Outline · Mealie · Vikunja · Gitea · code-server · IT-Tools · Stirling-PDF · Homepage · Glance · Echo · n8n · Actual-Budget · Wallos · Solis-Charge · NeatPlan · Shlink · SearXNG · OpenSpeedTest · UniFi · Website · iLO4 Fan Controller · Informate · Replicarr
🤖 AI · 4 apps - local inference & RAG
Ollama · Open WebUI · AnythingLLM · Arca
📊 Monitoring · 10 apps - metrics, logs, traces, status
Prometheus · Grafana · Alloy · Loki · Promtail · Graphite-Exporter · Uptime-Kuma · Scrutiny · Plausible · Exporters (TrueNAS / ProxmoxVE / AdGuard / iLO)
🗄️ Databases · 6 apps
PostgreSQL (CNPG) · MariaDB · Redis · MinIO · Qdrant · Mosquitto (MQTT) · pgAdmin
🌐 Network · 6 apps
Envoy Gateway · Cloudflare Tunnel · Cloudflare DDNS · Cloudflare DNS · k8s_gateway · Headscale
⚙️ System - kube-system, storage, cert-manager
Cilium · CoreDNS · Metrics-Server · Reloader · NFS-CSI (x2) · OpenEBS · VolSync · cert-manager
🔄 GitOps Workflow
┌──────┐ ┌──────────┐
│ me │── git push ─────────────▶│ │
└──────┘ │ GitHub │── pull main ──▶ Flux CD ──▶ Cluster
┌──────────┐ │ main │ (1m)
│ Renovate │── PR + auto-merge ──▶│ │
└──────────┘ └──────────┘
Update strategy - patch/minor container, helm, github-release, github-action, and mise updates auto-merge as standard merge commits. Major versions and critical infra (Talos, ClickHouse, Postgres, MariaDB, Redis, MinIO, Plex, Envoy, Cilium, cert-manager) are held for manual review via the Dependency Dashboard.
🗂️ Repository Layout
homeops/
├── bootstrap/ # one-shot Helmfile to seed the cluster
├── kubernetes/
│ ├── apps/ # one folder per workload, grouped by namespace
│ │ ├── ai/ default/ databases/ media/ monitoring/
│ │ ├── network/ storage/ cert-manager/ kube-system/
│ │ └── external-services/ # things outside the cluster (HA, iLO, Minecraft)
│ ├── components/ # reusable bits - volsync, sops, gatus probes
│ └── flux/ # Flux Kustomization graph + meta repos
├── talos/
│ ├── talconfig.yaml # talhelper input
│ ├── talenv.yaml # pinned Talos + K8s versions (Renovate-managed)
│ └── patches/ # node-level Talos patches
├── .taskfiles/ # task runners (flux, talos, volsync, k8s)
└── .renovaterc.json5 # update policy
Each app follows a consistent shape: ks.yaml (Flux Kustomization) + app/ (HelmRelease, OCIRepository, optional HTTPRoute and SOPS secret). Most apps use bjw-s/app-template.
🔌 Networking & Access
| Gateway | IP | Domain | Exposure |
|---|---|---|---|
envoy-internal |
192.168.1.7 |
*.iacob.uk |
LAN + WireGuard only |
envoy-external |
192.168.1.8 |
*.iacob.co.uk |
Public via Cloudflare Tunnel |
Public services sit behind a Cloudflare Tunnel: no inbound ports, DDoS protection at the edge, optional Authentik in front of sensitive apps. Internal services resolve via AdGuard Home split DNS so *.iacob.uk points at the internal Envoy, even from outside via WireGuard.
🔧 Operations
# Status overview
flux get all -A
kubectl get pods -A | grep -v Running | grep -v Completed
# Force a reconcile
task reconcile # whole cluster
flux reconcile ks <name> -n <ns> --with-source # one app
# Talos lifecycle
task talos:generate-config
task talos:apply-node IP=<ip>
task talos:upgrade-node IP=<ip>
# Backups (VolSync → TrueNAS MinIO)
task volsync:backup-all
task volsync:status
# Secrets (SOPS + age)
sops <file.sops.yaml> # edit
sops -e -i <file.sops.yaml> # encrypt in place
🙏 Credits
Built on the shoulders of the homelab community: primarily onedr0p/cluster-template, with patterns borrowed from onedr0p/home-ops, DavidIlie/home-cluster, and discoveries via kubesearch.dev.