Proxmox: Everything I’ve Learned Running a Home Lab
Proxmox VE is the hypervisor my whole home lab runs on: KVM virtual machines and LXC containers under one web UI, for free. This is the distilled version of what I’ve learned keeping it running - the notes live in Software_Tools.
- Proxmox core: https://bthek1.github.io/Software_Tools/03_0_Proxmox
- Storage backends: https://bthek1.github.io/Software_Tools/03_1_Proxmox_storage
- Containers: LXC & LXD
What Proxmox actually is
A Debian-based hypervisor that gives you two kinds of guest under one roof:
- KVM VMs - full hardware virtualisation. Any OS, real kernel isolation, live migration, PCI passthrough.
- LXC containers - OS-level containers sharing the host kernel. Near-zero overhead, boot in a second, but Linux-only and less isolated.
Plus a web UI, a clustering story, ZFS built in, and scheduled backups - no license fee. The whole reason to run it over bare Docker: you get both strong-isolation VMs and cheap containers, managed together.
VM vs LXC vs Docker - pick per workload
| KVM VM | LXC container | Docker | |
|---|---|---|---|
| Isolation | Strong (own kernel) | Medium (shared kernel) | Process-level |
| Overhead | High (full OS) | Very low | Low |
| Boot | ~30s | ~1s | ~1s |
| OS | Any | Linux only | App image |
| Passthrough | GPU/PCI/USB | Bind mounts, some devices | Volumes |
| Use for | Windows, k8s nodes, untrusted, GPU | Services, databases, utilities | App packaging |
My rule: LXC for anything Linux and long-lived (Postgres, Influx, services), VM when I need a different kernel, real isolation, or a GPU, and Docker inside an LXC or VM for app packaging. More in LXC & LXD.
The overhead gap is the whole reason to prefer LXC where you can:
The home lab it runs
flowchart TB H[Proxmox host] --> Z[(ZFS pool)] H --> BR[vmbr0 bridge] H --> V1[VM: Docker host] H --> V2[VM: GPU / ML] H --> L1[LXC: Postgres / Influx] H --> L2[LXC: services] V1 --> D[(Containers)] V2 -. PCI passthrough .- GPU[GPU] Z -. backups .-> PBS[Backup store]
Everything is provisioned reproducibly - see the companion post, Terraform + Ansible for a home lab - and some of what runs on it (energy monitoring) is in IotaWatt to battery ROI.
Storage: choose the backend before you create a guest
The single most confusing part at first. Proxmox abstracts several storage types, and the choice decides whether you get snapshots, thin provisioning, and shared storage. From Proxmox Storage:
| Backend | Snapshots | Thin | Shared | Best for |
|---|---|---|---|---|
Directory (dir) |
Only qcow2 | qcow2 | No | ISOs, backups, simple setups |
| LVM | No | No | No | Raw block, predictable |
| LVM-thin | Yes | Yes | No | Local VMs with snapshots |
| ZFS | Yes | Yes | No (local) | My default - snapshots, checksums, RAID |
| Ceph | Yes | Yes | Yes | Clusters, HA |
| NFS | qcow2 | qcow2 | Yes | Shared over LAN |
| CIFS/SMB | qcow2 | qcow2 | Yes | Windows/NAS shares |
What I settled on: ZFS local for guests (snapshots + bit-rot protection + easy send/receive backups), NFS for shared ISOs and dump. If you ever want a cluster with HA, that’s when Ceph earns its complexity.
What lives on the box (RAM allocation)
A snapshot of how host memory gets carved up - VMs are hungry, LXC services are cheap, and you always leave headroom for ZFS ARC.
GPU passthrough - the evening-eater
Passing a GPU into a VM is the most gotcha-dense thing I’ve done in Proxmox. The checklist that finally worked:
- Enable IOMMU in BIOS (VT-d / AMD-Vi) and on the kernel cmdline (
intel_iommu=on/amd_iommu=on). - Ensure the GPU sits in its own IOMMU group (ACS override only if you must).
- Blacklist the host driver and bind the GPU to
vfio-pciby vendor:device id. - VM must be q35 + OVMF (UEFI); add the PCI device with All Functions + PCIe.
- For consumer NVIDIA cards, hide the hypervisor so the driver doesn’t throw Code 43.
LXC is different - no true passthrough; you bind-mount /dev/dri and share the device. Full notes in Proxmox core.
Cloud-init, backups, and the habits that save you
| Habit | Why |
|---|---|
| Cloud-init templates | Spin a ready VM (user, keys, IP) in seconds, not a manual install |
Scheduled vzdump backups |
Snapshot-mode dumps to NFS/PBS; test a restore occasionally |
| ZFS snapshots before changes | Instant rollback when an upgrade breaks a guest |
| Bind-mount data, not store it in the guest | Rebuild the guest without losing data |
| Separate host + guest networks | A bridge (vmbr0) per role; keep management reachable |
The single biggest lesson: treat guests as disposable and data as sacred. Data on ZFS datasets / bind mounts, guests rebuilt from cloud-init + Ansible. When something breaks, you recreate the guest instead of nursing it.
Takeaway
Proxmox hits a sweet spot for a home lab: real VMs when you need isolation or a GPU, LXC when you want density, ZFS underneath for snapshots and integrity, and a web UI that makes it all legible. Start with LXC + ZFS, add cloud-init early, automate provisioning with Terraform + Ansible, and keep backups you’ve actually test-restored.