Skip to content

Architecture decisions

A homelab is a series of trade-offs. This page records the ones I'd expect to defend in a design review — why a particular tool or pattern was chosen, and where the boundary of that choice sits. It's deliberately written as reasoning, not as a feature list.

Proxmox vs VMware/ESXi

I run Proxmox VE as the hypervisor rather than ESXi or Hyper-V. The deciding factors: it's open-source with no licensing friction (Broadcom's 2024 changes to VMware's licensing and the end of the free ESXi tier made this more relevant, not less), it has first-class ZFS and LVM-thin support, and it exposes a clean REST/pvesh API that Ansible drives directly — DNS, timezone, backup jobs and updates are all managed declaratively. For a single-node homelab the enterprise features of vSphere add cost and operational weight I'd never use.

Immutable uCore vs traditional Linux

Both servers run uCore (image-based Fedora CoreOS) rather than a conventionally-managed Debian/Ubuntu host. The motivation is eliminating configuration drift: the OS is read-only, updates are atomic image swaps, and the entire machine can be rebuilt from an Ignition config plus Ansible. The cost is a less familiar operational model — you provision around the immutable base rather than editing it in place — but that constraint is exactly what keeps the servers reproducible.

Podman + Quadlets vs Docker Compose vs Kubernetes

Containers are defined as Quadlet unit files, not docker-compose.yml and not Kubernetes manifests.

  • vs Docker Compose — Quadlets make every container a native systemd service, so I get dependency ordering, restart policies, journald logging and timers for free, integrated with the rest of the host. No long-running Docker daemon.
  • vs Kubernetes — Kubernetes would be the wrong tool here. There's no multi-node scheduling, autoscaling or rolling-deploy requirement that justifies an API server, etcd and a control plane on two machines. Running k8s would mean operating the cluster instead of the services. The homelab is where I demonstrate knowing when not to reach for Kubernetes — at work, where those requirements do exist, the answer is OpenShift.

Rootless (monitoring) vs root (kontti) Podman

This is a deliberate security boundary, not an inconsistency. monitoring runs Podman rootless as the unprivileged core user: the observability stack needs no host privileges, so keeping it rootless limits the blast radius if a container is compromised. kontti runs rootful because several of its workloads need direct device access (the AMD GPU for transcoding and AI inference) and shared host paths, which is materially simpler to manage as root. The principle: rootless by default, rootful only where a concrete capability requires it.

Self-hosted vs SaaS

The boundary I apply: data gravity and privacy stay on-prem; undifferentiated heavy lifting can go to SaaS. Photos (Immich), media, notes, and now local AI inference (Ollama) are self-hosted because the whole point is that the data never leaves the network — the plex-sync semantic search pipeline runs entirely locally for the same reason. I don't self-host things where a managed service is clearly better and carries no sensitive data (e.g. public DNS registration, certificate issuance via ACME). Self-hosting is a means to control and learning, not an ideology.

Flat LAN vs VLAN segmentation

The network is currently a single flat LAN behind OPNsense, with no VLAN segmentation. For a small, trusted home environment the added complexity of inter-VLAN firewall rules and tagged switch ports isn't yet justified. The honest trade-off: a compromised IoT device sits on the same broadcast domain as everything else. VLAN segmentation — at minimum isolating IoT/ESPHome devices from servers and management — is the most defensible next step, and the point at which I'd introduce a managed switch. Documenting it as a known, deliberate gap rather than an oversight is itself part of the decision.

Borg/Borgmatic vs alternatives

Backups use Borg driven by Borgmatic, targeting the Synology NAS, which in turn replicates off-site to Backblaze B2 for a full 3-2-1 posture. Borg gives deduplicated, compressed, encrypted, append-only archives; Borgmatic wraps it in a declarative YAML config with database dump hooks and Prometheus push-gateway integration for monitoring. Compared to restic the feature set is close — the deciding factor was Borgmatic's hook ergonomics and the append-only mode protecting against ransomware-style deletion. A cluster-oriented tool like Velero would be overkill without Kubernetes. The honest open gap here is restore testing, documented as such rather than glossed over.

Cloudflare Workers + Git integration vs GitHub Actions

This site deploys through Cloudflare's native Git integration rather than a GitHub Actions workflow: Cloudflare watches the main branch, runs the MkDocs build in its own build environment, and publishes the static site/ output as Workers static assets (the only repo-side config is wrangler.jsonc). The alternative — a GitHub Actions job running mkdocs build and wrangler deploy — would add a workflow file, a Cloudflare API token to store as a secret, and a second system to keep in sync, in exchange for control this project doesn't need. Keeping the pipeline inside Cloudflare means one connected repository and zero CI credentials to manage. Direct push to main (no PR gate) is a deliberate choice for a single-author docs site where the cost of a bad deploy is a quick revert, not an outage.

My experience

The architecture didn't emerge from a single design session — it grew from two things I already trusted. In my previous role I used OpenShift, where the operating system is atomic and every workload runs in a container, so the uCore + Podman model felt natural rather than novel. On my laptop I run Aurora Linux, part of the same Universal Blue family; the cloud-native philosophy, rolling freshness and day-to-day stability there convinced me the same approach would work for servers.

Borgmatic was an early choice I made before realising that uCore ships with Restic out of the box. Restic might be a better fit, but Borgmatic has worked reliably after the initial learning curve, so the motivation to switch hasn't been strong enough.

Self-hosting has paid off on two fronts: cost and privacy. Keeping photos, media and AI inference on-prem means no recurring cloud bills for storage or compute, and no data leaving the network.

VLAN segmentation remains undone — honestly because this is a home lab and I live alone, the threat model doesn't yet justify the effort of tagged ports and inter-VLAN firewall rules.