Homelab
A basement data center, and the crew of agents that runs it at night
There is a rack of computers in the basement doing the jobs most people pay Google, Apple and Amazon for: photos, files, the smart home, the cameras, the backups. A set of automated helpers checks on it overnight and sends me one email a day.

| Nodes | Two Proxmox hosts (a Dell OptiPlex desktop and a retired HP laptop) plus a tie-breaker vote on the camera box |
|---|---|
| Storage | TrueNAS SCALE on an OptiPlex 990: a mirrored pair of 8 TB SAS drives, served over NFS |
| Virtual machines | Ten: DNS ×2, Home Assistant, the Docker host, Tailscale, metrics, a Claude host, a VPN-bound downloader, an agent runner, and a sandbox |
| Containers | About 30 on the Docker host, a dozen more on the media box |
| Network | GL-iNet MT6000 on OpenWrt, five VLANs, T-Mobile 5G behind carrier NAT |
| Front door | A small VPS running Caddy and Authelia, reached over Tailscale. No port forwarding |
| Cameras | Frigate on an Intel N95 mini PC with two Reolink cameras, GPU-accelerated detection |
| Backups | Nightly VM images to a separate pool, Backblaze B2 offsite through rclone crypt |
| Monitoring | Uptime Kuma (about 110 checks), Beszel, Grafana |
| Power | CyberPower UPS on NUT. Twelve unplanned outages and counting |
What it is
A homelab is a personal data center running at home. Instead of letting Google, Apple or Amazon hold my photos, files and smart home, I run the servers myself. They sit in a basement rack in the woods of central Virginia and they handle everything from the dog’s camera alerts to the backups of this website.
What started as a Raspberry Pi running Home Assistant is now two Proxmox hosts, a TrueNAS storage box, a dedicated camera machine, a media server, a managed switch and a small VPS, plus a team of software agents that does the overnight maintenance.
Why I do this
I value my privacy, and I don’t trust Google to respect it. So I’ve replaced their services one at a time with things I control: a NAS instead of Google Drive, Proton Mail instead of Gmail, Nextcloud for file sync, Immich for photos, Kagi for search. I use Linux because I feel the same way about Microsoft as I do about Google.
The value isn’t only privacy or dodging subscriptions. It’s understanding. Google Photos just works. Setting up Immich took days and a full re-import when the first approach failed. But now I understand photo metadata, machine learning inference, PostgreSQL, Docker, NFS mounts and reverse proxies in a way I never would have otherwise. This lab has produced plenty of both.
What it runs today
Compute. Two Proxmox hosts form a cluster. The main one is a Dell OptiPlex desktop with a 10 GbE SFP+ card; the second is an HP laptop with a broken hinge that lives on as a headless node and, usefully, has its own battery. A third vote for the cluster comes from the camera box, so losing any one machine doesn’t stall the others. Between them they run ten virtual machines: two Pi-hole DNS resolvers (one per host, so DNS survives either going down), Home Assistant OS, a Docker host, a Tailscale subnet router, a metrics box, a Claude Code machine, a VPN-bound download box, an agent runner and an isolated sandbox.
Storage. TrueNAS SCALE on the old OptiPlex 990, with a mirrored pair of 8 TB enterprise SAS drives behind an LSI controller in IT mode. Everything that matters lives on ZFS and reaches the VMs over NFS: photos, documents, media, the git server’s repositories, this site. A separate 1 TB pool takes the nightly VM backups so a bad backup night can’t fill the main pool.
Services. The Docker host carries the household: Nextcloud (native, not containerised), Immich for photos, Paperless for documents, Forgejo as my own GitHub, Uptime Kuma, a Homepage dashboard, Actual Budget, Umami analytics, a Collabora office server, and a handful of small bridges I wrote myself. The media box runs Jellyfin, Navidrome and Audiobookshelf with the usual *arr stack behind them.
Smart home. Home Assistant with Zigbee2MQTT, Z-Wave JS, Matter and ESPHome. Node-RED is the automation engine, with sixteen flows for things like the alert digest, the garage door (below), the dog rules, and a watchdog that power-cycles the internet gateway when the uplink dies. The ESPHome devices are my own builds: a 433 MHz bridge for the ceiling fans, a ratgdo board on the garage opener, and an Emporia Vue energy monitor reflashed to run locally. The fan bridge and the energy monitor have their own pages under Electronics.
Cameras. Frigate on an Intel N95 mini PC with OpenVINO object detection on the integrated GPU. A Reolink Duo floodlight camera watches the driveway and a TrackMix PTZ watches the backyard. Detections flow over MQTT into Home Assistant; the phone only buzzes for people, cars and packages, and for the dogs when the dog rules say so.
Network. A GL-iNet MT6000 on OpenWrt with five VLANs: management, trusted, isolated IoT, cloud-dependent IoT, and guest. Internet is T-Mobile 5G, which means carrier-grade NAT and no inbound ports, so the public face of everything is a small VPS running Caddy and Authelia that reaches the house over Tailscale. SQM shaping on the router keeps the 5G uplink from collapsing under the offsite backups.
Backups. Nightly Proxmox VM images to the backup pool, ZFS snapshots on the main pool, and offsite copies to Backblaze B2 through rclone crypt, rate-limited so they don’t saturate the uplink. The music and video libraries stay home by choice; they’re replaceable.
The garage door
The automation people ask about most. The door opens when I drive home and closes if I drive away right after opening it. No buttons, no notifications when it works, exactly one when it fails. The obvious version (“open when the phone enters the home zone”) opens the door every time I walk the dogs, so the rules grew, each one from a real trip.
The hardware. A ratgdo32, a small ESP32 board wired to the opener’s control terminals, reads the door’s actual position from the opener instead of guessing from a tilt sensor. It runs ESPHome and shows up in Home Assistant as a door with position, plus the obstruction beam and the light. Three wires, twenty minutes.
Arrival. The phone changes from away to home. The door opens only if the phone was recently connected to the car over Bluetooth (so a walk doesn’t count), I had been gone long enough for it to be a real trip rather than GPS wobble, the door is closed or parked in the vent position, and the flow hasn’t opened it in the last few minutes.
Departure. The phone leaves home while connected to the car. The door closes only if the flow had just opened it; a door that was already open is someone else’s business. On hot days it closes to a crack instead of fully, so the dogs and cats can get out of the heat. If the door is still open a couple of minutes after I leave, I get one message.
Where the rules live. All of the decision logic is plain functions in one JavaScript file: data in, a decision and a sentence explaining it out. The file never touches the door; the Node-RED nodes do that and call the rules, so the logic can be tested on a laptop with the exact situations from real trips before it goes anywhere near the opener. The tuning numbers are variables I can change in the Node-RED editor without touching code. The file opens with a long comment explaining JavaScript to a C programmer, because that is who I am when I come back to it in six months.
The door still can’t tell my car from my wife’s; the Bluetooth rule only knows my phone.
The night shift
The part I’m most pleased with is the least visible. Since autumn 2026 a team of Claude Code agents runs the lab’s maintenance while I sleep, all of it scheduled on the laptop node and all of it bounded by rules I wrote down first.
A security agent runs at 03:35 and applies patches inside a standing approval, filing anything riskier as a question. A reliability round follows at 04:20: it restarts containers that didn’t come back after a reboot, remounts lost NFS shares, checks backup freshness and keeps the known-issues list honest. A responder wakes on any Uptime Kuma alert, diagnoses, and may only run named runbook actions; everything else becomes a question. A weekly documentation audit checks about 170 machine-verifiable claims against the live systems and rewrites the docs when reality has moved. An updater reads Home Assistant release notes and installs the harmless updates.
At 06:30 I get one email and one push: what needs me, what was done, what went wrong. I answer with a few words (“yes REL-3 Saturday”, “no SEC-24”) and those answers are recorded as single-use approvals. Every infrastructure write any agent makes, interactive sessions included, is appended to a ledger with secrets redacted. A pause switch stops all of them in one command.
The documentation itself is the source of truth: a repository of YAML facts and prose runbooks that a deterministic script turns into the agents’ memory and my Obsidian vault. No agent is allowed to regenerate it with a language model; if the output is wrong, the source gets fixed.
What still goes wrong
Power. Twelve unplanned outages so far. The UPS and the NUT chain now shut the rack down cleanly, and the main Proxmox host boots itself when mains returns, but the TrueNAS box, the media box and the camera box still need their power buttons pressed. The TrueNAS box and the laptop node have dead CMOS batteries that forget the “power on after loss” setting. Replacing coin cells is on the list.
The backup disk. The backup pool is a single shingled (SMR) drive, which stalls under exactly the long sequential writes a VM backup produces. Fleecing on the Proxmox side and a trimmed schedule made it livable; a proper disk would make it go away.
The laptop node. A software reboot hangs it about half the time, so nothing is allowed to reboot it unattended. Its single USB network adapter is the one single point of failure I haven’t engineered out.
Memory pressure on the media box and on Home Assistant after long uptimes, a Roomba integration that silently freezes after the robot reboots, and a music library guardrail that has been off since June. All known, all on the list.
What’s next
Moving the unattended jobs off the laptop onto a small runner VM on the main host, so the night shift survives the laptop. Replacing the 5G internet with something that has a real public address, at which point the B2 backups can finally be re-uploaded at full speed. Coin cells. And a review board, once a month, that reads the ledger and tells me which of my own rules have stopped making sense.
The journal entries below are from earlier in the lab’s life. Some of that hardware is gone.
Journal
The Deep Audit
February 2026: checking every documented claim against the live systems, then locking SSH down.
Infrastructure Hardening
Late January 2026: a security audit, offsite backups to B2, and a failed experiment.
TrueNAS Migration
January 2026: splitting storage from compute. A week-long journal.