A Kubernetes homelab running real services - fully managed as code, automated as possible, and open source to show everyone how to break k8s :D. In this repository every deployment, every network policy, and every secret lives here. Some are SOPS encrypted, others use 1password connection. Renovate opens PRs, konflate reviews them, CI validates them, and the auto-merge pipeline deploys them to the cluster via flux.
Side note: Though I mentioned this is automated some PRs like cilium upgrade, rook update are very critical and I have minimal time for my cluster and cannot jump in when PR automatically breaks my cluster for that reason.
This repository has three types of PR. This way I try to safely automate as possible the upgrade process:
- automated
- deployed during release train (Friday/Saturday as during the weekend I can fix stuff)
- critical which can be merged only by me.
It is also a reference for anyone curious about running Kubernetes at home. Whether you want to borrow a single app configuration or bootstrap your own cluster from scratch, everything you need is here.
My setup is a three Talos Linux control-plane nodes - a minimal, immutable, API-driven Kubernetes distribution - running on Proxmox with Rook-Ceph for distributed storage.
| Area | What's running |
|---|---|
| Networking | Cilium - eBPF-based CNI, kube-proxy replacement · Gateway API - dual gateways with cert-manager TLS · cloudflared - tunnel ingress · external-dns - DNS sync |
| Storage | Rook-Ceph - distributed block storage · csi-driver-nfs - NFS media shares · VolSync + Kopia - PVC backup and replication |
| Secrets | SOPS + Age - encrypted secrets in Git · external-secrets + 1Password Connect · cert-manager - Let's Encrypt TLS |
| GitOps | Flux CD - GitOps operator · Renovate - automated updates · Reloader - pod restart on config change · KEDA - event-driven autoscaling |
| Observability | VictoriaMetrics + VictoriaLogs - metrics and logs · Grafana - dashboards · Gatus - health checks · Coroot - APM · Kromgo - badges · Chaski - alert routing |
| Utilities | Spegel - P2P image mirroring · Metrics Server · Intel GPU Plugin - hardware transcoding · Dragonfly - Redis-compatible cache |
All Kubernetes nodes are Talos Linux machines. Two are baremetal and one is a VM running on Proxmox.
| Device | OS Disk | Data Disk | RAM | Details |
|---|---|---|---|---|
| Proxmox VE | NVMe | NVMe | 64GB | Main hypervisor |
| k8s-0 (VM) | 250GB | 250GB | 32GB | Talos control-plane, Intel ARC GPU |
| k8s-1 | eMMC 30GB | 250GB | 32GB | Talos control-plane |
| k8s-2 | 1TB SSD | 250GB | 32GB | Talos control-plane, e1000e driver |
| TrueNAS SCALE (VM) | SSD 20GB | 40TB ZFS | 64GB | NFS/SMB storage - 4x10TB HDD RAIDZ2 |
| Unifi UDM Pro | SSD 14GB | HDD 1TB | 4GB | Router and security gateway |
| Unifi Switch 16 PoE | N/A | N/A | N/A | PoE+ switch |
| Offsite VM | 60GB | 8TB | 8GB | Offsite backup target |
Every dependency update follows the same fully-automated path from Renovate to the cluster - no human toil for routine changes.
flowchart LR
RV[Renovate<br/>opens PRs hourly] --> LB[Labeler<br/>classifies PR by<br/>labels and path]
LB --> KL[Konflate<br/>renders cluster diff<br/>flags cautions]
KL --> FG{CI gates<br/>flate + yayamlls}
FG --> AM[Auto-Merge<br/>evaluates policy<br/>daily at 02:00 UTC]
AM -->|gates passed| MG[Merge PR]
MG --> FX[Flux<br/>applies to cluster]
Auto-merge policy - the rules that decide whether a Renovate PR gets merged automatically or waits for human review:
| Category | Min age | Day constraint | Konflate gate | Auto-merge |
|---|---|---|---|---|
Patch / digest (type/patch, type/digest) |
2 days | Any | No failures, no cautions | Yes |
Minor (type/minor) |
3 days | Fri–Sat (Europe/Berlin) | No failures, no cautions | Yes |
Major - GitHub Actions (type/major + renovate/github-action) |
2 days | Any | No failures (cautions allowed) | Yes |
Major - other (type/major) |
- | - | - | Manual |
| Rook-Ceph, Cilium, Flux, Dragonfly | - | - | - | Manual |
area/talos label |
- | - | - | Manual |
- Quiet window: Sunday 00:00–05:00 UTC - no merges scheduled (Talos upgrade window).
- Sleep between merges: 5 minutes (10 for minor release train) to let Flux reconcile before the next merge.
- Konflate renders the full cluster diff for each PR, posts a blast-radius summary comment, and gates merges on render status. It runs inside the home network and is reachable as a best-effort check from GitHub Actions - the label/age/day gates are the hard floor.
- Safe PRs are squash-merged automatically; high-blast-radius changes (Ceph, Talos, non-action majors) always require a human review.
📁 kubernetes # Cluster defined as code
├─📁 flux # Flux configuration - meta repos, cluster kustomization
├─📁 apps # Applications grouped by namespace
└─📁 components # Reusable Kustomize components (common labels, volsync, keda)
📁 talos # Talos Linux node configuration, patches, and secrets
📁 scripts # Bootstrap, backup, and validation helpers
📁 bootstrap # Core-operator Helmfile for initial cluster bootstrapping| App | Description |
|---|---|
| Plex | Media server and streaming |
| Plex-Music | Music streaming via Plexamp |
| Sonarr | TV show collection manager |
| Radarr | Movie collection manager |
| Prowlarr | Torrent/usenet indexer manager |
| Sabnzbd | Usenet downloader |
| Unpackerr | Auto-extracts downloaded archives |
| Recyclarr | Syncs TRaSH Guides profiles |
| FlareSolverr | Cloudflare anti-bot bypass |
| Seerr | Media request management |
| Tautulli | Plex statistics and monitoring |
| Komga | Comic/manga/ebook library |
| Kapowarr | Comic book collection manager |
| App | Description |
|---|---|
| Home Assistant | Home automation platform |
| Glance | Personal dashboard |
| Karakeep | Bookmark manager |
| Paperless-ngx | Document management with OCR |
| Docmost | Collaborative wiki and notes |
| AFFiNE | Knowledge base workspace |
| Atuin | Shell history sync server |
| App | Description |
|---|---|
| Cloudflare Tunnel | Secure external ingress |
| Echo Server | Ingress/connectivity testing |
| Proxmox | Reverse proxy to hypervisor |
| TrueNAS | Reverse proxy to storage |
| Minecraft | Game server |
This repo is a living reference - borrow what you like, ignore what you don't. Here is how to go from zero to your own cluster.
- A domain with DNS managed by a provider external-dns supports (Cloudflare, Route53, etc.).
- A secrets backend - this repo uses 1Password Connect + external-secrets, but anything with an external-secrets provider works.
- An Age key for SOPS-encrypted secrets (
age-keygen). - Workstation tooling:
talosctl,flux,just,helmfile,talhelper,sops,kubectl. - Nodes: at least one Talos-capable machine (bare metal, Proxmox VM, or any hypervisor). Three control-plane nodes are recommended.
This repo is opinionated and personal. These are the hardcoded values you will need to change:
| Find | Replace with |
|---|---|
juno.moe (Cloudflare zone) |
Your domain |
EU (WAF country filter) |
Your country |
192.168.69.x (node IPs) |
Your subnet |
| 1Password Connect references | Your secret backend |
| Proxmox / TrueNAS backends | Your hypervisor and NAS |
external.juno.moe (tunnel hostname) |
Your tunnel endpoint |
kromgo.juno.moe, konflate.juno.moe |
Your monitoring hosts |
Once you have edited talos/patches/ to match your hardware, follow these steps:
just talos-genconfig # Regenerate Talos configs from patches
just bootstrap-age-key # Generate SOPS Age key (age.key)
just bootstrap-talos # Apply Talos config, bootstrap cluster, fetch kubeconfig
just bootstrap-apps # Deploy core operators (Cilium, cert-manager, Flux) via HelmfileAt this point Flux takes over and reconciles everything under kubernetes/ into the cluster.
- onedr0p/cluster-template - a friendlier fork target and step-by-step guide.
- kubesearch.dev - search homelab Kubernetes configs for app-level examples.
- k8s-at-home - community hub for running Kubernetes at home.
This project is part of the home operations community (previously k8s-at-home). Join us on Discord for discussion, help, and inspiration.
Feel free to check out my blog at axell.dev - also open source - which includes a hardware walkthrough covering what worked and what didn't.
See LICENCE.
