back to tinkering
~/tinkering/k8s-homelab · git show

Kubernetes Homelab

A self-hosted, enterprise-grade GitOps platform, built to keep production instincts sharp: immutable infrastructure, declarative everything, secure secrets, and monitoring that would pass a real on-call rotation.

// role
Solo — design & build
// timeline
2026 — present
// where
Helsinki, FI · self-hosted
// status
● live & evolving
architecture.excalidraw — git → flux → k3s reconciliation loop
Diagram of the homelab's GitOps reconciliation loop: a Git repo is the source of truth; Flux reconciles it into a k3s cluster running eight namespaces, including kube-system, flux-system, monitoring, renovate, linkding, audiobookshelf, homepage and website; the in-cluster Renovate CronJob scans the repo hourly and opens pull requests back into it, closing the loop; SOPS-encrypted secrets committed to the repo are decrypted by Flux at apply time; Grafana, running in the monitoring namespace, is exposed externally via a Traefik ingress at grafana.lukadimnik.com.
01

// overview

Most homelabs are a pile of docker run commands no one can reproduce. I wanted the opposite: a platform run exactly the way a disciplined org would run production, so the muscle memory transfers directly to the platform work I do for teams.

The result is an immutable, declarative Kubernetes platform where the Git repository is the single source of truth. Nothing is changed by hand. Push to main, and the cluster reconciles itself toward the desired state, including its own OS, its workloads, its monitoring, and its secrets.

02

// why bother

I could run everything on one box with a docker-compose file and call it a day. I don't, on purpose. As an EM, I don't get to spend every day heads-down in Kubernetes manifests, so I built myself a place where I still do. Every constraint I add here (no SSH, no manual kubectl apply, no plaintext secrets) is one I'd defend in a design review at work, and it keeps those instincts sharp for when a team actually needs them.

It's also just genuinely fun to be the one holding the pager for your own infrastructure. When something breaks at 11pm, there's no one else to escalate to, which has taught me more about failure modes than any postmortem I've read.

03

// what I built

01 · GitOps & declarative infra

The repo is the cluster

Flux reconciles the live cluster against Git continuously. Helm releases are standardized and version-pinned; every environment follows the same Kustomize base/overlay pattern rather than ad-hoc setup.

02 · Lightweight by design

Ubuntu Server + k3s

Nodes run plain Ubuntu Server with k3s on top, a stripped-down Kubernetes distribution built for edge and resource-constrained environments. Same API as full-fat Kubernetes, a fraction of the footprint, which matters when the "data center" is a shelf in a closet.

03 · Observability

End-to-end monitoring

A complete monitoring and alerting architecture built on Prometheus and Grafana, metrics, dashboards and alert rules designed to surface problems the way they would on a real on-call rotation.

04 · Secrets & automation

Secure & self-maintaining

Secrets are encrypted in Git with SOPS. Renovate keeps images and charts current, with AI-assisted changelog review on the updates, so maintenance is continuous and low-touch instead of a quarterly scramble.

04

// what it proves

0 manual
Zero hand-applied changes — every deploy flows through Git and Flux reconciliation.
100%
Reproducible: the entire platform — OS, workloads, monitoring — is declared as code.
auto·updated
Renovate + AI-assisted changelog review keep images and charts continuously current.
05

cat stack.txt

# platform
os/runtime = Ubuntu Server · k3s · Kubernetes
gitops = Flux · Helm

# operations
observability = Prometheus · Grafana
secrets = SOPS (encrypted-in-git)
automation = Renovate · AI changelog review
Ubuntu Serverk3sKubernetesFluxHelmPrometheusGrafanaSOPSRenovate
06

// what's next

backlog

Cost & power tracking

A small dashboard for what this hobby actually costs to run, because eventually someone's going to ask.

backlog

Stateful workloads

Add persistent storage and start hosting a few personal databases, then see how the backup and restore story holds up under real data.

someday

GPU workloads

NVIDIA device plugin for Kubernetes, with Ollama running Llama 3 on the 1080 Ti, scheduled via node affinity, and a small app consuming the inference endpoint, deployed through Flux.

someday

IaC for the nodes

Ansible playbooks that install k3s, configure UFW, set up SSH keys, and join workers, with the goal of provisioning a bare-metal node from scratch with a single command.

Want this discipline
on your platform?

This is how I approach real systems too: declarative, observable, reproducible.