At the start of the year, my homelab was a museum: a Supermicro X10-era pfSense box, a Dell R630 running ~20 Docker containers on bare-metal Debian, a hacked-together JBOD full of media, an R730XD crammed with a GPU it had no room for, and the Synology DS218+ that started it all six years ago. It… worked. It also sounded like a jet engine and had the failure domain of a Jenga tower. I was terrified of every update; every deploy involved a prayer 🙏
The noise, performance, and nerves eventually caught up to me. So I consolidated. This page is the tour.
The build
The Dells and JBOD were retired into a single Supermicro CSE-846 — 4Us/24-bays of compute (I had to transplant the power distribution board from a donor chassis to run 1200W PSUs and power the GPUs, which is the kind of problem I enjoy having).
| Part | What it is | Notes |
|---|---|---|
| Board | Supermicro H12SSL-CT | 2x onboard 10GbE, onboard SAS HBA |
| CPU | AMD EPYC 7543P | 32 cores, 64 threads |
| RAM | 256 GB DDR4 ECC | 8× 32GB mixed 2400/2933; in this economy… 🫠 |
| Boot | 2× 1 TB SSD | |
| Storage | 8× 14 TB HDD | RAIDZ2 (media + config) |
| GPU #1 | NVIDIA Quadro P400 | Plex transcodes |
| GPU #2 | NVIDIA RTX 3090 Turbo | AI inference |
The old pfSense router survived the purge; it’s ancient, but with 6× 10GbE NICs it has earned its keep. The UniFi gear (two switches, three APs) got upgraded to 10GbE along the way, fed by 2.5 Gb cable, which is (sadly) the best my street can do. The Synology stuck around too, though it now has exactly one job: hosting Proxmox Backup Server as a VM.
One box, seven networks, total isolation
First and foremost, the lab is physically isolated from the home LAN. I can build and break all I want without risking downtime for the rest of the house. This was probably the #1 non-negotiable 😅
The brains of the lab runs Proxmox VE, and everything inside lives in a VM. pfSense trunks seven VLANs into the host, so each VM sits on a network scoped to its job: management, infrastructure, a DMZ for anything public-facing, media, AI, a storage network for NFS, and a temporary/testing playground where the real breakage is allowed to happen.
Inter-VLAN traffic goes through the firewall like everybody else. The only thing reachable from the internet is a single reverse proxy in the DMZ.
The fleet
10 VMs, each owning one slice of the lab:
| VM | Runs |
|---|---|
| edge | Caddy (sole public ingress), Authentik SSO, Vaultwarden |
| infra | Forgejo (git + CI), private container registry, UniFi controller |
| data | Shared PostgreSQL, MySQL, Redis, MongoDB |
| media | Plex (with P400 transcoding), the whole *arr suite, Transmission-over-VPN, etc. |
| monitoring | Prometheus, Grafana, et al |
| web | Assorted websites (like this one!) |
| ai | llama.cpp on the 3090, OpenWebUI |
| deploy | The CI runner that deploys everything else |
| testing | Disposable playground, excluded from backups |
| automation | Home Assistant OS (managed independently because HAOS bows to no configuration management) |
The whole lab is a git repo
Here’s the part I’m actually proudest of: none of this is hand-configured. The entire stack, from hypervisor prep to running containers, is four layers of infrastructure-as-code:
A bootstrap script turns a fresh Proxmox install into a configured host (ZFS, VLAN bridges, GPU passthrough). Packer bakes a Debian 13 cloud-init template. Terraform clones it into the fleet. Ansible configures each VM and renders the Compose stacks. Secrets are sops-encrypted with age and committed right alongside the code. Initially scary, but the repo is the single source of truth, and the lab can be rebuilt from it end to end.
GitOps is the glue
Standing the lab up is a laptop job, but day-to-day changes ship themselves. A push to my self-hosted Forgejo kicks off a pull-based deploy loop:
The runner diffs the push, maps changed files to stacks, and redeploys only what changed so a one-line compose edit never restarts an unrelated container. Nothing accepts inbound connections: the runner polls out to Forgejo, and Forgejo mirrors out to GitHub as an offsite copy that runs nothing. A self-hosted Renovate instance files the update PRs (with a 7-day gate so I’m never the first one to run a fresh tag).
RAIDZ2 is not a backup, but this is
Three tiers of backups: nightly VM images to Proxmox Backup Server (the Synology’s retirement gig), file-level archives of the important bits with databases dumped consistently first, and an offsite sync of the whole PBS datastore to Backblaze B2.
Restores are tested, keys are escrowed, and I (finally) sleep fine.
Was it worth it?
A couple of servers/space-heaters, a JBOD, and a pile of regret became one quiet, efficient box with room to grow, and a lab I can git log. When something breaks, the fix is a commit. When I add something new, the runbook is already written.
Ten out of ten. Would swap a PDB again.