The Docker Trap
You start running Home Assistant in Docker. It works great. Automations run. Your wife’s HomeKit stuff stays synced. Then you want to add a Zigbee coordinator — a little USB dongle that talks to your motion sensors, lights, and temperature sensors.
Docker doesn’t like USB passthrough. Or more accurately, it hates it with the fiery passion of a scorned DBA. The port mappings get weird. The device binds and unbinds. You reboot the container and suddenly nothing can find /dev/ttyUSB0 anymore.
You reach for the Home Assistant Add-on store, hoping someone’s built a Zigbee2MQTT container for you. Nope — the Add-on store isn’t available in Docker mode. It’s only available in Home Assistant OS (HAOS).
That’s where Proxmox comes in. Run HAOS as a Proxmox VM, and you get:
- Full Add-on store — all official add-ons, community add-ons, the works
- Native USB passthrough — USB coordinators work properly
- Supervisor features — system updates, add-on management, restore points from within HA
- Snapshots and backups — both HA’s built-in snapshots AND Proxmox’s full VM backups
- Easy resource allocation — bump vCPU and RAM without rebuilding
- Alongside other VMs — run Proxmox, HAOS, Debian server, and a media box on the same iron
If you already have Proxmox running your home lab, this is the cleanest way to self-host Home Assistant.
Four Ways to Run Home Assistant (and Why OS is the One)
Before we jump into Proxmox specifics, let’s clear up the confusion. Home Assistant has four flavors:
Home Assistant OS (HAOS)
The full package. Runs on dedicated hardware or as a VM. Includes Supervisor (the agent that manages add-ons), the add-on store, automatic updates, and snapshots. This is what you want.
Home Assistant Container
A Docker image. Runs in Docker/Podman. You manage the container yourself. No Supervisor, no add-on store, no built-in backups. Works, but you’re flying without a net.
Home Assistant Core
Bare Python install. You run the service yourself, manage dependencies, handle updates. Only for people who like pain.
Home Assistant Supervised
Core + Supervisor running on a generic Linux box. Deprecated. You’ll see it in old forum posts. Ignore it.
The catch: The add-on store is locked to HAOS and Supervised only. If you want Zigbee2MQTT, ESPHome, InfluxDB, or any of the 200+ community add-ons without building them yourself in Docker, you need HAOS.
Running HAOS in a Proxmox VM is the self-hoster’s sweet spot. You get the full feature set, hardware separation, and all the Proxmox goodies (snapshots, backups, easy resource changes, live migration).
Why Proxmox for Home Assistant
Proxmox gives you three killer advantages:
1. Snapshots and Backups (Layered)
Home Assistant has its own snapshot system — it backs up your database, automations, and integrations. But Proxmox also has full VM snapshots. Run both.
HA snapshots = application-level restore points. Proxmox snapshots = “rewind the entire VM to this exact moment.” If an HA update breaks something, roll back in HA. If the whole VM catches fire, restore from Proxmox.
2. USB Passthrough Without Docker Nonsense
Proxmox can pass a USB device directly to a VM. No binding/unbinding chaos. Your Zigbee coordinator stays bound. Z2M or the ZHA add-on sees it every time.
3. Coexistence
Your Proxmox box already runs other things — a media server, a Debian maintenance box, a backup target. HAOS gets its own VM with its own resources. No resource contention, no port conflicts, clean separation of concerns.
Plus, Proxmox handles resource allocation cleanly. CPU and RAM overcommit work like they should. One VM crashing doesn’t touch the others.
Setting Up HAOS on Proxmox
You have two paths: the official way (download QCOW2, import, configure) and the community way (tteck’s scripts). The official way is more work but teaches you how Proxmox VM imports work. The community way is faster.
Path 1: The Official Flow (QCOW2 Import)
Home Assistant publishes a QCOW2 image for KVM/Proxmox. It’s the official, blessed way.
Step 1: Download the image
Grab the latest HAOS QCOW2 from the Home Assistant downloads page or the release repo. The file is huge (compressed), so this takes a minute.
# On the Proxmox host, or download locally and scpcd /tmpwget https://releases.home-assistant.io/os/qemu/homeassistant-qemu-x86-64.qcow2.xz# Decompress (takes a while, produces ~15 GB file)xz -d homeassistant-qemu-x86-64.qcow2.xz# Verify the file existsls -lh homeassistant-qemu-x86-64.qcow2Step 2: Create a VM and import the disk
In Proxmox, create a new VM. Assign it:
- VM ID: Pick something memorable (100, 200, etc.)
- Name:
homeassistantor similar - Memory: Start with 4 GB (4096 MB). Home Assistant usually uses 1-2 GB; the rest buffers disk cache.
- CPUs: 2 cores is enough. Bump to 4 if you have a lot of automations or slow hardware.
- Disk: Leave it blank for now. We’ll import the QCOW2.
Once the VM exists, import the disk:
# On the Proxmox host# List storage where the disk will live (usually 'local-lvm' or 'local')pvesm status
# Import the disk into Proxmox storage# Format: qm importdisk <vmid> <source> <storage> [--format <fmt>]qm importdisk 100 /tmp/homeassistant-qemu-x86-64.qcow2 local-lvm
# This creates a new disk in Proxmox storage. Check the Disks tab in the Proxmox UI,# or verify on the command line:lvdisplay | grep vm-100Step 3: Attach the disk to the VM
In the Proxmox UI, go to VM 100 → Hardware → Add → Hard Disk. Select the imported disk (vm-100-disk-1 or similar) and attach it as SCSI or VirtIO (VirtIO is faster, but SCSI is safer if you’re unsure).
Alternatively, use qm:
# Attach the disk to the VM# Format: qm set <vmid> -<disktype><index> <disk-identifier>qm set 100 -scsi0 local-lvm:vm-100-disk-1
# Verifyqm config 100 | grep scsiStep 4: Boot and configure
Start the VM. Home Assistant will boot, detect the disk, and initialize. This takes 2–3 minutes on first boot.
Once it’s running, access the web UI at http://<vm-ip>:8123 (or homeassistant.local:8123 if your network has mDNS). Create your account, and you’re in.
Path 2: Community Helper Scripts (Faster)
If you want to skip the manual import, tteck’s Proxmox Helper Scripts include a Home Assistant installer. It downloads, decompresses, and configures everything in one script.
# SSH into the Proxmox host# Run the helper script (check the repo for the latest URL)bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/haos.sh)"Follow the prompts. It’ll ask for VM ID, memory, storage, etc. Much faster than the manual route.
Note: These scripts are community-maintained and updated regularly. Check the repo to make sure they’re current before running.
Sizing: CPU, RAM, and Disk
Home Assistant is lightweight. Here’s a real starting point:
| Resource | Minimum | Comfortable | Large Setup |
|---|---|---|---|
| vCPU | 1 | 2 | 4 |
| RAM | 2 GB | 4 GB | 8 GB |
| Disk | 10 GB | 32 GB | 64 GB |
Why these numbers?
- 1 vCPU works, but your automations will queue under load. Add a second core and automation latency drops.
- 2 GB RAM is the real floor. Below that, HA swaps to disk and slows down. 4 GB is the sweet spot for most home labs.
- Disk: HA’s database is tiny (~100 MB for most setups). Add-ons and snapshots eat space. 32 GB gives you breathing room; 64 GB if you plan heavy snapshots.
For a Proxmox VM:
# Inside the Proxmox console, or via qm command# Check the current VM sizeqm config 100 | grep -E 'memory|cores|scsi'
# To resize (when the VM is powered off):# Add 2 more GB of RAM (2 GB = 2048 MB)qm set 100 -memory 6144
# Add a vCPUqm set 100 -cores 4
# Extend the disk (while running or stopped, but safer when stopped)lvextend -L +32G /dev/pve/vm-100-disk-1# Then tell HA to expand its filesystemFor most home labs, start at 2 vCPU, 4 GB RAM, 32 GB disk. You can resize later if needed.
USB Passthrough: Connecting Your Coordinator
The big reason you moved to HAOS on Proxmox is USB passthrough. This is where Docker really falls apart.
Find the Device
First, identify your USB device on the Proxmox host:
# On the Proxmox host, list all USB deviceslsusb
# Example output:# Bus 001 Device 042: ID 10c4:ea60 Silicon Labs CP2102N USB to UART Bridge Controller# Bus 001 Device 043: ID 1a86:55d4 QinHeng Electronics CH340 serial converter
# The ID format is VendorID:ProductID (10c4:ea60 in the first example)# Note the bus and device number (Bus 001 Device 042)Pass the Device to the VM
Edit the VM config to add the USB device. You can do this via the Proxmox UI (Devices → Add → USB Device) or via command line:
# Option 1: Pass by Bus and Port (safest for Zigbee coordinators)# Format: qm set <vmid> -usb<index> <bus>-<port>qm set 100 -usb0 1-2
# Option 2: Pass by VendorID:ProductID (less reliable if you plug it into a different port)qm set 100 -usb0 10c4:ea60
# Verifyqm config 100 | grep usbBus:Port is better. If you have multiple USB devices, pass by bus and port number. That way, even if you unplug and replug, the VM always sees the right device.
Inside the VM
Once the VM sees the USB device, Home Assistant’s ZHA or Zigbee2MQTT add-on will find it automatically. No more /dev/ttyUSB0 binding drama.
If the device disappears after a reboot, check:
- Is the USB device still plugged in?
- Did Proxmox rebind the device to the host? (This happens sometimes with power loss or unexpected shutdown.)
- Force an unbind on the Proxmox host:
# Find the device's USB pathlsusb -v | grep -A 5 "10c4:ea60"
# Unbind from the host and rebind to VFIO (for passthrough)# This is a last resort — usually Proxmox handles itecho "1-2" | tee /sys/bus/usb/drivers/usbfs/unbindNetwork: Bridged vs. VLAN
By default, the Proxmox VM gets a bridged network interface — it’s on the same subnet as your Proxmox host.
For most home labs, this is fine. Home Assistant can reach your local devices, and you can reach its web UI from anywhere on the network.
If you want Home Assistant on a separate VLAN (isolated from your main network for security), configure that in Proxmox when you create the VM. Proxmox’s network bridge setup handles VLANs naturally.
Default setup works. If you have strong reasons to isolate, fine — but for home automation, bridged is simpler and less to debug.
Backups: HA Snapshots + Proxmox Backups
Here’s the strategy: run two levels of backups.
Level 1: Home Assistant Snapshots
Inside Home Assistant, go to Settings → System → Backups and create a backup. HA snapshots your entire config, automations, integrations, and database.
Pros: Application-aware, easy to restore from the web UI, fast. Cons: Stored inside the VM. If the VM catches fire, the backups burn too (unless you back up the snapshots externally).
Level 2: Proxmox VM Backup
Use Proxmox’s backup agent to snapshot the entire VM periodically. This is a full-disk image backup — it backs up everything, including HA’s snapshots.
Create a script on the Proxmox host:
#!/bin/bash# backup-haos.sh - Daily backup of Home Assistant VM
VMID=100BACKUP_DIR="/mnt/backup/proxmox"TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Create a snapshot of the VM (no downtime)qm snapshot $VMID backup-$TIMESTAMP
# Export the snapshot (this creates a full backup file)vzdump $VMID --dumpdir $BACKUP_DIR --mode snapshot
# Clean up old snapshots (keep last 7)# (Optional, but snapshots accumulate)qm listsnapshot $VMID | tail -n +8 | awk '{print $1}' | while read snap; do qm delsnapshot $VMID $snapdone
echo "Backup of HAOS (VM $VMID) completed: $TIMESTAMP"Schedule it via cron:
# Add to crontab on the Proxmox host# 2 AM daily backup0 2 * * * /root/backup-haos.sh >> /var/log/haos-backup.log 2>&1Result: Two independent backups. HA’s snapshots inside the VM. Proxmox’s full VM backup outside. If something goes wrong, you can restore at either level.
Updating Home Assistant
Updates happen in the HA web UI (Settings → System → Updates). When you click “Update,” HA downloads the new version and installs it. This usually takes 2–5 minutes.
Before updating, take a Proxmox snapshot:
# On the Proxmox hostqm snapshot 100 before-upgrade-$(date +%Y%m%d)
# Check the snapshot existsqm listsnapshot 100If the update breaks something, restore from the snapshot in a few seconds:
qm rollback 100 before-upgrade-20260629Snapshots are almost free on modern storage (ZFS or LVM with CoW). Take them liberally.
Common Pitfalls and Fixes
USB Device Unbinding
Problem: Your Zigbee coordinator works, then suddenly Z2M can’t find it.
Cause: Proxmox lost the USB binding to the guest VM.
Fix: Restart the VM, or manually rebind the device:
# On the Proxmox hostecho "1-2" | tee /sys/bus/usb/drivers/usb/bindThen restart the Z2M add-on inside HA.
Time Skew
Problem: Zigbee devices drop off after a while. Z2M reports “device is offline.”
Cause: The VM’s clock drifted. Zigbee coordinators are timing-sensitive.
Fix: Enable NTP inside the VM:
# Inside the HA VM console (or SSH if enabled)timedatectl set-ntp ontimedatectl statusOr set the Proxmox host’s time to be authoritative:
# In Proxmox, ensure the host's NTP is syncedtimedatectl statusRunning Out of Disk
Problem: HA slugs along, database gets corrupted, add-ons fail to install.
Cause: The 32 GB disk is full.
Fix: Extend the disk while the VM is running (no downtime):
# On the Proxmox hostlvextend -L +32G /dev/pve/vm-100-disk-1Then inside the VM, expand the filesystem:
# Inside the HA VM (via console)df -h # Check current sizeresize2fs /dev/sda1 # Expand EXT4 partitiondf -h # Verify new sizeYou’re In
You now have Home Assistant OS running natively on Proxmox, with USB passthrough working, snapshots ready, and a layered backup strategy.
Your Zigbee coordinator stays bound. The add-on store opens up. Automations run without Docker’s weirdness. And if something breaks, you roll back in seconds.
This is the self-hoster’s setup — simple, reliable, and just comfortable enough to let you focus on the actual home automation instead of wrestling with container networking.
Your 2 AM self will thank you when your motion sensors work reliably for months straight.