The lab didn’t start as a lab. It started as services accreting onto whatever machine happened to be on — a media server here, a script there, everything sharing one filesystem and one fate. The failure that changed it was boring and total: one bad upgrade, and everything went down together, with no isolation between the thing I broke and the things I cared about, and no undo. I rebuilt from scratch, twice.
That’s the problem this lab solves. Not “host services” — break things without breaking everything, and always have a way back. The solution became one Proxmox VE host carrying about twenty LXC containers and a handful of VMs, behind a UniFi network that does the segmentation work. Every post on this blog is now written, built, and pushed from a container in that lab. No seven-node cluster blinking in a rack — the interesting lessons are in how much one box can carry, and where the isolation boundaries actually earn their cost.
The host, and the undo button
The box is built around an Intel Core Ultra 9 285K — 24 threads on one
socket — with 96 GB of RAM, running Proxmox VE 9.2 on kernel
7.0.14-4-pve. Proxmox gives me three primitives behind one API: full
VMs (QEMU/KVM), system containers (LXC), and ZFS storage. At a typical
moment the host sits under 1% CPU with ~18% of memory committed — the
first surprise the lab taught me is that the constraint on a homelab
server is almost never compute. It’s RAM and storage layout.
Storage is where the two rebuilds paid off. Everything is ZFS, split by
what the disks are good at: a fast NVMe pool for container roots and VM
disks, a big spinning pool (~12 TiB raw between them) for bulk data, and
a separate pool that exists only to receive backups. Each container’s
root is its own dataset (the blog’s workspace lives on a subvol under
the fast pool), which buys the three things I actually use daily:
- Snapshots before anything risky. Instantaneous, and rollback is one command. The “no undo” failure that started this lab can’t happen anymore — and it has saved me twice since.
- Per-dataset quotas instead of pre-carved disk images — the pool is shared and containers take what they’re allotted.
- Checksums on every block. ZFS detects the bit-rot that a plain RAID mirror silently propagates — the distinction I unpacked in RAID: what it does and doesn’t.
The VM/container line is a sizing lesson
I wrote about what a container really is — namespaces plus cgroups, no guest kernel. What the lab taught me is that this definition becomes a budget. My first instinct was VMs for everything, because VMs feel like “proper” isolation. Then I did the arithmetic: a VM pins its allocation — give it 8 GB and that memory is spoken for, plus a whole guest kernel. Twenty services as VMs would have blown through 96 GB before doing any work. An LXC container shares the host kernel; its “8 GB” is a cgroup ceiling, and unused memory stays in the host page cache where it does something useful.
So almost everything is LXC: a reverse proxy, the Cloudflare Tunnel connector, a Tailscale node, a photo library, a vector database, an LLM chat UI, a code-server, a Docker host for compose-shaped things, some monitoring, and the container that runs the coding agent maintaining this site — 4 vCPUs and 8 GB, strange enough to deserve its own post.
The VMs are the exceptions that prove the rule, each needing its own
kernel: a Windows 11 guest, an identity/auth appliance I want strongly
isolated, and an emulated ARM machine for cross-architecture testing.
The tell from inside a container: systemd-detect-virt says lxc, and
uname -r shows the host’s -pve kernel. One kernel, many userspaces.
The network does the isolation
The second lesson came from the network side, and it arrived the way these lessons do — as a “wait, that can see this?” moment. A flat network means the cheapest, least-trustworthy device on it (a smart plug, a guest’s phone) sits one hop from the hypervisor’s management interface. Compute isolation is worthless if the network hands out adjacency for free.
So the other half of the lab is a UniFi stack — a UCG Ultra gateway, a
PoE switch, and a WiFi 6 access point — with the flat-network problem
solved the way the homelab networking
post prescribes: segmentation
by trust. The management network hangs off 192.168.0.0/24, and
everything else lives in its own VLAN and 10.10.x.0/24 — IoT gadgets,
guest WiFi, office gear, public-facing servers, NAS traffic, VPN
clients, an experiment sandbox for things I don’t trust yet, and an
identity/auth segment. A dozen VLANs sounds like enterprise cosplay
until the first compromised smart plug can’t see your hypervisor. Then
it sounds like the minimum.
SSIDs map onto the same segments — the IoT network is 2.4 GHz-only, which is where small embedded things like my wake-on-LAN gateway live.
Nothing is port-forwarded. Remote access is Tailscale (mesh VPN in, zero inbound holes), and the few deliberately public services go out through a Cloudflare Tunnel — an outbound connection from a container, so the LAN never accepts unsolicited traffic. The blog itself doesn’t touch any of this: it’s static files on Cloudflare’s edge, because a residential connection is exactly where a public website should not live.
There’s also one machine outside the house: an Oracle Cloud free-tier VM running an LLM API proxy — keys stay off the LAN, and it survives local power cuts.
Takeaways
- The lab exists to learn on. Its real product isn’t uptime — it’s the lessons: isolation boundaries, sizing budgets, and recovery paths you only understand after breaking them.
- One well-specced Proxmox box covers a remarkable amount of homelab; RAM and storage tiering are the real constraints, not CPU.
- Prefer LXC over VMs for trusted Linux services — shared-kernel density is the whole game on a single host. Reserve VMs for foreign kernels and hard isolation boundaries.
- ZFS snapshots before every risky change; quota datasets instead of fixed images; a dedicated backup pool that does nothing else.
- Segment by trust: VLANs per role, IoT quarantined, management network unreachable from anything untrusted. VPN in, tunnel out, forward nothing.
- Next in this series: the fleet of bare-metal machines around this box — and what a hypervisor can’t do.