Welcome to My Homelab
6 min readUpdated
I’m Cody Blevins. This site is where I publish the systems I actually build and operate: a small, production-like homelab, the products running on top of it, and the operational lessons that come out of keeping the whole thing alive.
What started as “can I run LLMs locally?” turned into a more durable theme: make operations boring enough that the interesting work can happen on top of them. If a thing is useful, I want it to be deployable, observable, reversible, and documented well enough that I can come back to it three months later without re-learning it from scratch.
TL;DR
- The homelab is not just for model hosting anymore. It now backs public docs, playgrounds, demos, and product surfaces on this site.
- The current core stack is Harvester -> K3s -> GitLab CI -> Harbor -> Flux, with explicit GPU lanes for text, vision, embeddings, voice, and image workloads.
- The projects you will see most often here are FlexInfer, Loom / Loom Core / Mills, MentatLab, fi-fhir, and the public FlexDeck-powered demos.
- The current focus is less “can it run?” and more “can it ship repeatedly without surprises?”
The Philosophy
My day job is integration architecture and production systems. The homelab is where I can try ideas without asking for a budget or a change window, but still keep myself honest:
- build it like a service, not a one-off,
- measure it (even if the numbers are “directional”),
- and keep the failure modes visible.
The Hardware Zoo
It’s a mix of enterprise hardware and repurposed PCs. I optimize for “easy to repair” and “good enough,” not perfection.
The Backbone: Dell R730xd
The heart of the operation is a Dell PowerEdge R730xd running Harvester HCI. It handles virtualization and gives me a clean substrate for K3s control-plane and worker VMs, plus Longhorn-backed storage that is good enough to be operationally boring.
From this server I run, among other workloads:
- three dedicated K3s control-plane VMs,
- multiple worker VMs for general compute,
- and storage pools that back the cluster.
The current K3s control plane is not limited to those three VMs. Some physical GPU hosts participate as control-plane servers or etcd voters, while others are etcd-less. I keep that membership in GitOps and monitoring rather than pretending a static blog diagram is the authority.
The Power Duo: AMD Radeon RX 7900 XTX (x2)
I run two RX 7900 XTX cards and split them by workload so contention is predictable instead of mysterious:
- Quality lane (
cblevins-7900xtx): always-on text inference plus larger on-demand models when I want more quality or reasoning headroom. - Text + video lane (
cblevins-5930k): a second text-serving lane shares the card with demand-driven video workloads under explicit priority and preemption rules.
The Legacy Branch
NVIDIA GTX 980 Ti - The old guard (cblevins-gtx980ti). It is no longer the star of the show, but it still earns its keep as a small media lane and a useful reminder that “legacy” hardware often sticks around longer than the architecture diagram wants to admit.
AMD Radeon VII - The retrieval lane (cblevins-radeonvii). It keeps embeddings and reranking off the busier 7900 XTX cards, with other experiments admitted through explicit shared groups rather than assumed spare capacity.
The Edge
Raspberry Pi 5 - An arm64 K3s node named ubuntu. It is restricted to explicitly compatible, lightweight workloads; Longhorn replica scheduling is disabled there, and monitoring treats its limited memory as an expected constraint. It is the quiet counterpoint to the much louder basement hardware.
The Gaming PC Graveyard
Several machines in the cluster are former gaming rigs. I like hardware with a known failure history and parts I can replace.
The Software Stack
All of this hardware is operated through GitOps. Desired state lives in version control, GitLab CI builds artifacts, Harbor stores images, and Flux reconciles the cluster. There are still stateful systems and recovery procedures behind that sentence; Git is the desired-state source, not a magical backup of every byte.
Kubernetes (K3s)
The cluster runs K3s, with dedicated control-plane VMs, Harvester-backed workers, physical GPU hosts, and the arm64 edge node. The exact node and etcd membership changes over time. The important part is the operating model:
- GitLab CI builds artifacts,
- Harbor stores images,
- Flux reconciles desired state,
- and the cluster is treated like a projection of Git, not a hand-edited appliance.
All configuration lives in the platform/gitops repo. Here's a peek at the structure:
platform/gitops/
├── clusters/
│ └── k3s/ # Flux entrypoints
├── harvester/
│ ├── vms/ # Control-plane and worker VM definitions
│ └── flux/ # Harvester-managed infrastructure
├── k3s/
│ ├── ai/flexinfer/ # Inference control-plane resources
│ ├── ci/ # GitLab runners and BuildKit
│ ├── flux/ # Workload reconciliation
│ ├── monitoring/ # Prometheus, Grafana, and alerting
│ ├── nodes/ # Node labels, roles, and taints
│ └── security-posture/ # Cluster security policy
└── Dockerfiles/ # Shared platform images
This “desired state as code” approach makes rebuilds and audits tractable. Bootstrapping Flux restores declared resources, while stateful data still depends on backups, storage recovery, and service-specific restore paths.
What the cluster is backing now
The biggest change since I first wrote this post is that the homelab is now backing real public surfaces, not just private experiments:
- FlexInfer: the inference control plane and routing work behind my GPU posts, config contracts, and playgrounds.
- Loom / Loom Core / Mills: multi-assistant MCP config sync, agent lifecycle tooling, persistent context, fleet visibility, and gated delivery workflows.
- MentatLab: the operator-facing directed acyclic graph (DAG) surface for explicit workflow steps and approvals.
- fi-fhir: healthcare integration docs, runnable examples, and playground tools for source profiles and mappings.
- flexinfer-site itself: multi-project docs, case studies, and a growing set of public demos driven by the same stack I use internally.
- FlexDeck public visualizations: sanitized, rate-limited operational views for cluster topology, model status, CI pipelines, and metrics summaries through a read-only service account.
AI / runtime stack
The runtime mix is intentionally pragmatic:
- FlexInfer for model routing, custom resources, GPU scheduling, leasing, and deployment control
- vLLM and llama.cpp on the active serving paths; the old MLC-LLM manifests, caches, and persistent volumes were retired on August 19, 2026
- diffusers on the dedicated Maxwell image lane, with demand-driven video workloads on the gfx1100 lane
- FlexDeck as the operations surface for live cluster and pipeline views
I still experiment with backends. The difference now is that experiments happen inside a clearer platform boundary instead of in a pile of one-off containers.
Storage
Longhorn provides distributed block storage across the cluster. It is not the fastest option, but it is Kubernetes-native, understandable, and good enough for the kinds of failures I actually want to debug.
Important data gets replicated. Model artifacts and experiments get more pragmatic treatment based on how expensive they are to rebuild.
What I am tightening next
The next wave of work is less about standing the system up and more about hardening the public edges:
- Verify the monitoring rollout in-cluster:
/metrics, theServiceMonitor,PrometheusRule, and Grafana panels exist. The remaining work is target/rule visibility and service-specific Alertmanager routing. - Finish the public-edge audit: ingress and route rate limits plus read-only RBAC are deployed. The next proof is a focused security review and restricted pod/network policy work.
- Make deployment artifacts immutable: finish the move from mutable image tags to immutable tags or digests through GitOps.
- Keep docs and playgrounds honest: maintain parity between source repos, synced docs, examples, and interactive tools as the product surfaces change.
That is the through-line for this setup now. The homelab is still where I experiment, but the bar is higher than “it works on my LAN.” The useful question is whether the system can survive repeated deploys, public traffic, a failed storage path, and future me.
Related Articles
Comments
Join the discussion. Be respectful.