How to Install Home Assistant OS on Proxmox VE β€” Full Setup Guide 2026
homelab

How to Install Home Assistant OS on Proxmox VE β€” Full Setup Guide 2026

Ricardo Gil
September 14, 2026
16 min read
#proxmox #home-assistant #self-hosting #homelab #zigbee
πŸ›’

Products in This Post

Affiliate links

As an Amazon Associate I earn from qualifying purchases at no extra cost to you.

I resisted adding Home Assistant to my homelab for longer than I care to admit. I already had Jellyfin, Immich, Vaultwarden, and Navidrome running on my Proxmox stack, and the thought of managing yet another service felt like diminishing returns β€” especially when I only had a handful of smart bulbs and a Zigbee sensor or two. But after a couple of months reading about what people were automating and watching my home network go completely unmanaged, I finally caved. Three weeks later, Home Assistant is talking to my Zigbee devices, sending Telegram alerts when my washing machine finishes, and triggering a script that dims the lights and opens Jellyfin on my TV. Here is the exact setup I use and the commands that got me there.

Why I Finally Added Home Assistant to My Proxmox Setup

The tipping point was a single use case: I wanted one dashboard that unified everything in my homelab β€” not just the services I was self-hosting, but the physical world around them. I already had Uptime Kuma watching my service uptime and Traefik routing HTTPS traffic, but nothing that could reach into a Zigbee bulb or read a temperature sensor. Home Assistant is the obvious answer, and I knew from reading the Proxmox forums that the correct way to run it alongside LXC workloads is to give it a dedicated VM rather than forcing it into a container.

I run my entire homelab on a Beelink EQ12 Mini PC (~$189) with Crucial 32GB DDR4 RAM (~$59) and a WD Black 2TB NVMe SSD (~$129). The machine idles around 9W with five LXCs active, so I was cautious about what adding a full VM would do to my power draw and thermal headroom. After two weeks of running Home Assistant OS alongside my existing stack, the VM adds roughly 1–2W at idle and maybe 150–200 MB of RAM. On a 32 GB machine with Proxmox, that is a rounding error. The trade-off is completely worth it for what you get in return.

The other reason I went with the full Home Assistant OS (HAOS) VM approach rather than a Container install is the supervisor. HAOS ships with a built-in supervisor that manages add-ons, automated snapshots, and OS updates. If you try to run Home Assistant as a plain Python process or Docker container in an LXC, you lose the entire add-on ecosystem β€” Mosquitto, Zigbee2MQTT, Z-Wave JS UI, ESPHome β€” and those add-ons are what make Home Assistant genuinely powerful for a homelab. The VM path trades a bit of RAM for a dramatically simpler operational experience.

HAOS VM vs LXC Container: The Honest Answer

This question comes up constantly in homelab communities, so I want to give you a direct answer based on what I actually tested rather than repeating the documentation. There are three ways to run Home Assistant on Proxmox: Home Assistant OS as a VM (the official recommended path), Home Assistant Container inside a privileged LXC running Docker, and Home Assistant Supervised on a Debian VM. I ran the first two back to back on my Beelink before settling on HAOS VM.

Home Assistant Container in a privileged LXC is functional if you only need the core automations engine β€” YAML automations, integrations that use cloud polling, and the Lovelace UI all work fine. What you lose is the Supervisor, which means no add-on store. Mosquitto, Zigbee2MQTT, Z-Wave JS UI, and ESPHome each become separate containers you have to manage yourself. USB device passthrough to an LXC is also more involved than passing a USB stick to a VM β€” the LXC approach requires editing /etc/pve/lxc/CTID.conf directly and often runs into permission issues on first boot. If you want a deep dive on the general LXC versus Docker trade-offs, my Docker vs LXC on Proxmox guide covers the architectural differences in detail.

Home Assistant OS as a VM is what I settled on, and what I recommend for anyone who wants the full experience without fighting the tooling. The disk image is pre-built by the HA team, the supervisor handles updates and snapshots in one click, and every add-on and integration works exactly the way the documentation describes. The cost is a bit more RAM (I allocate 2 GB and it runs comfortably) and the inability to install arbitrary system packages inside HAOS without breaking the supervisor. That trade-off is completely worth it for 99% of homelab use cases. The add-on ecosystem alone justifies it.

Prerequisites Before You Start

Here is exactly what I had in place when I set this up on my Beelink. Proxmox VE 8.x running and accessible via the web UI and SSH. At least 32 GB of free disk space on your storage pool (I use local-lvm on my NVMe). A Zigbee USB dongle if you plan to use Zigbee devices β€” I use the Sonoff Zigbee 3.0 USB Dongle Plus, which works out of the box with both Zigbee2MQTT and ZHA. And a terminal open to your Proxmox host, either via the web shell or SSH.

On the networking side: give Home Assistant a static IP before you do anything else. I manage DHCP leases through my router and reserved the IP there before the VM even booted for the first time. Home Assistant does not play well with dynamic IPs because integrations, companion apps, automations that reference the host, and Traefik routing rules all depend on a stable address. Pinning the IP takes two minutes and prevents you from having to reconfigure everything from scratch when the lease expires.

If you plan to expose Home Assistant through Traefik β€” which I strongly recommend β€” make sure Traefik is already running and accepting dynamic file provider configs from a config directory. I wrote the full Traefik setup in my Traefik v3 reverse proxy guide. Get that running first, then come back here for the Home Assistant–specific routing config.

Step 1 β€” Download the HAOS QCOW2 Image on the Proxmox Host

The Home Assistant project publishes a QCOW2 virtual disk image that Proxmox can import directly. SSH into your Proxmox host (or open the web shell from the Proxmox dashboard under your node β†’ Shell) and run the following. Check the HAOS releases page on GitHub for the current version number and update the variable accordingly β€” the filename format is consistent across releases.

bash
# Download the HAOS QCOW2 image β€” update the version to the latest stable release
HAOS_VERSION="13.2"
cd /var/lib/vz/template/iso

wget "https://github.com/home-assistant/operating-system/releases/download/${HAOS_VERSION}/haos_ova-${HAOS_VERSION}.qcow2.xz"

# Extract β€” this takes 60–90 seconds
xz -d "haos_ova-${HAOS_VERSION}.qcow2.xz"

# Confirm the file extracted correctly (should be ~1.4 GB)
ls -lh haos_ova-${HAOS_VERSION}.qcow2

The compressed download is around 400–500 MB depending on the release. Once xz finishes and you see the .qcow2 listed at roughly 1.4 GB, you are ready to create the VM shell in Proxmox. Do not skip the size check β€” a corrupted or partial download will fail silently at the import step and waste your time.

One thing I appreciate about the HAOS distribution model is that the team ships a purpose-built image for each hypervisor type. The OVA-derived QCOW2 is tuned for KVM-based virtualization with VirtIO drivers already baked in, which means you get near-native disk and network throughput without having to install guest agents manually. This is the same reason I do not bother with generic Debian VMs for Home Assistant β€” the HAOS image handles all of that for you.

Step 2 β€” Create the VM Shell in Proxmox

I use the Proxmox web UI to set up the VM configuration because it is faster to click through network, CPU, and BIOS settings visually, then import the disk via command line. In the Proxmox web UI click Create VM and walk through the wizard with these exact settings.

On the General tab: pick a VM ID (I used 200) and name it homeassistant. On the OS tab: select Do not use any media β€” we are importing our own disk. On the System tab: set Machine to q35 and BIOS to OVMF (UEFI). This is critical β€” HAOS requires UEFI and will not boot with the legacy SeaBIOS option. When prompted to add an EFI disk, accept. On the Disks tab: delete the default virtio disk that Proxmox adds automatically (we are importing the HAOS disk in the next step, so the placeholder is just noise). On the CPU tab: 2 cores minimum. On the Memory tab: 2048 MB. On the Network tab: your main bridge, usually vmbr0.

bash
# After the VM shell is created in the UI, import the HAOS disk
# Replace 200 with your actual VM ID
# Replace 'local-lvm' with your storage pool name if different

qm importdisk 200 /var/lib/vz/template/iso/haos_ova-13.2.qcow2 local-lvm

# The output will say something like:
# unused0: local-lvm:vm-200-disk-1
# Go to the VM Hardware tab in the UI, find "Unused Disk 0",
# click Edit and add it as a VirtIO Block device (/dev/vda).

Once the disk is attached, open the VM's Options tab and set the boot order so your imported disk is first in the sequence. Disable the CD-ROM from the boot list entirely. I missed this step the first time I set it up and spent a few minutes staring at a PXE boot screen before I figured out what happened. After fixing the boot order, confirm the VM hardware panel shows: the EFI disk, your imported HAOS disk as a VirtIO block device, the network adapter, and 2048 MB RAM.

Step 3 β€” USB Passthrough for a Zigbee Dongle

If you have a Zigbee or Z-Wave USB stick you want to pass directly into the Home Assistant VM, configure that before first boot. In the Proxmox web UI, go to your VM's Hardware tab, click Add β†’ USB Device. I always pass by vendor and product ID rather than USB port, because port-based passthrough breaks if you ever replug the dongle into a different port on the hub.

bash
# On the Proxmox host shell β€” identify your USB dongle IDs
lsusb

# Example output for the Sonoff Zigbee 3.0 dongle:
# Bus 001 Device 003: ID 10c4:ea60 Silicon Labs CP210x UART Bridge

# Use those vendor:product values in the Proxmox UI dialog.
# Select "Use USB Vendor/Device ID" when adding the USB device.

After adding the USB device entry in the hardware panel, the dongle will appear inside the HAOS VM after boot. In Home Assistant, the recommended path to reference it is through the by-id symlink rather than the raw /dev/ttyUSBx path, because the ttyUSB number can change on reboot. You will find the stable path at something like /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_... β€” use that exact path when configuring Zigbee2MQTT or the ZHA integration.

If you are not using a USB Zigbee or Z-Wave dongle and instead plan to rely on a network-based coordinator (like a Sonoff Zigbee Bridge Pro running Tasmota with MQTT) or purely on Matter/Thread over Wi-Fi, you can skip this step entirely. USB passthrough is only needed for serial-connected coordinators. The rest of the VM setup is identical either way.

Step 4 β€” First Boot, Onboarding, and Initial Config

Start the VM from the Proxmox web UI and watch the console output. HAOS takes about 90 seconds to boot on the first run because it resizes the filesystem to fill the virtual disk and initializes the supervisor. Do not interrupt this process β€” I rebooted it once thinking it had hung, and that just kicked off the full initialization sequence again from the start. Watch for the line that prints the IP address and the URL β€” that is your signal that it is ready.

bash
# From another machine on your network β€” wait for this to resolve
ping homeassistant.local

# Or just navigate directly to the VM's IP
# http://<your-vm-ip>:8123

The onboarding wizard walks you through creating an owner account, setting your home location for local sunrise/sunset automations, and running an initial device discovery scan. The discovery scan surprised me β€” it auto-found my Jellyfin server, a Sonos speaker, and two Chromecasts before I had configured anything. Once onboarding is complete, go immediately to Settings β†’ System β†’ Backups and enable automatic daily backups with at least 7 days of retention. This is the one housekeeping step most guides skip and the one you will regret skipping the first time an update goes wrong.

The other early configuration I make on every fresh install is reducing the recorder history. By default Home Assistant logs state changes for all entities for 10 days. On a homelab machine that is running 24/7 with energy monitoring plugs updating every second, that database can grow to several gigabytes quickly. I trim it to 5 days and exclude high-frequency sensors from the recorder entirely. Edit this in /config/configuration.yaml via the File Editor add-on (which you will install in a moment).

yaml
# /config/configuration.yaml β€” recorder tuning
recorder:
  purge_keep_days: 5
  exclude:
    entity_globs:
      - sensor.*_power          # exclude high-frequency power sensors
      - sensor.*_current
      - sensor.*_voltage

Step 5 β€” HTTPS via Traefik and Trusted Proxy Config

Routing Home Assistant through Traefik follows the same file-provider pattern I use for every other service on my homelab. The one Home Assistant-specific detail is that you must tell HAOS it is sitting behind a reverse proxy, otherwise it will reject requests with mismatched origin headers and the frontend will appear broken β€” websocket connections fail silently, the dashboard goes stale, and automations look like they are not triggering when they actually are.

yaml
# In /config/configuration.yaml (edit via File Editor add-on)
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 192.168.1.50  # Replace with the IP of your Traefik LXC
yaml
# Traefik dynamic config β€” save as /etc/traefik/conf.d/homeassistant.yml
# on your Traefik LXC
http:
  routers:
    homeassistant:
      rule: "Host(`ha.yourdomain.com`)"
      entryPoints:
        - websecure
      service: homeassistant
      tls:
        certResolver: letsencrypt

  services:
    homeassistant:
      loadBalancer:
        servers:
          - url: "http://192.168.1.200:8123"

After reloading Traefik (it picks up file provider changes without a restart) and restarting Home Assistant to apply the configuration.yaml change, I could reach the dashboard at https://ha.yourdomain.com with a valid Let's Encrypt certificate. The live dashboard, real-time state updates, and the WebSocket push that powers the Lovelace UI all work correctly with this setup. If you want to go further and add Headscale for remote access outside your home network without opening ports, the pattern is identical to what I describe in the Headscale on Proxmox LXC guide.

One gotcha I hit on my first attempt: I added the trusted_proxies entry but forgot to restart Home Assistant after saving configuration.yaml. The File Editor add-on saves the file but does not apply it β€” you need to go to Developer Tools β†’ YAML β†’ Check Configuration, and then Restart. After that restart everything clicked into place and the Traefik integration worked exactly as expected. Keep that restart step in mind if you find the dashboard returning 400 errors after setting up the reverse proxy config.

Essential Add-ons to Install in the First Week

The Supervisor add-on store is one of the primary reasons to run HAOS as a VM rather than a container. All of these are available directly in the HA web UI under Settings β†’ Add-ons β†’ Add-on Store. Install them in roughly this order since some depend on others being configured first.

  • Mosquitto broker β€” Install this first. It is the MQTT broker that Zigbee2MQTT and many other add-ons publish to. Default config works out of the box; it listens on port 1883 on localhost inside the VM.
  • Zigbee2MQTT β€” Converts Zigbee device traffic into MQTT messages and exposes every device as a Home Assistant entity. Point it at the by-id serial path for your USB dongle and the Mosquitto broker on localhost:1883. Most Zigbee devices pair with a single button press after this is running.
  • File editor β€” A minimal web-based text editor for configuration.yaml and other HAOS config files. Essential for the trusted_proxies change above and any YAML configuration you need to make.
  • Studio Code Server β€” VS Code in the browser, running inside the VM. It includes the Home Assistant YAML extension with autocomplete for entity IDs and service calls. I switch to this for anything more complex than a two-line automation.
  • Samba share β€” Exposes the /config directory as a Windows network share. Useful when you want to bulk-edit YAML files or copy configuration between instances from your development machine.

Beyond these five basics, the ecosystem goes deep: ESPHome for flashing custom firmware to ESP32/ESP8266 devices, Node-RED for visual automation flows, the Matter server add-on for Thread/Matter device support, and Frigate NVR if you want AI-powered camera motion detection running locally. I am currently testing Frigate with a USB Coral TPU on the same Beelink β€” that will be its own post once I have it properly benchmarked.

One add-on worth mentioning that often gets overlooked: the Advanced SSH & Web Terminal add-on gives you a proper shell inside the HAOS environment. This is useful when you need to inspect the filesystem, check supervisor logs directly, or run a one-off command without going through the Proxmox web shell. It is not the same as root SSH access to the underlying Alpine OS, but it covers 90% of the debugging scenarios you will run into as you build out your automations.

Real-World Resource Usage on the Beelink

After running this setup for three weeks alongside my five LXCs β€” Jellyfin, Navidrome, Vaultwarden, Uptime Kuma, and n8n β€” here is what I actually see in the Proxmox summary panel. The HAOS VM with Mosquitto, Zigbee2MQTT, and about 40 active entities idles at 170–220 MB of RAM and 1–3% CPU. During automation bursts (a motion sensor triggers a scene that changes six lights simultaneously) I see a brief spike to 8–12% CPU for about a second, then back to baseline. That is entirely acceptable on a Proxmox host with 32 GB available.

The NVMe sees regular light writes from the SQLite recorder database logging state changes. The recorder tuning I described earlier (5 days, excluding high-frequency sensors) keeps the database around 400 MB in my setup β€” manageable. If you are considering hardware for a homelab that runs HAOS alongside several LXC services, the Beelink EQ12 I started on handles the combined load comfortably. My Beelink EQ12 vs GTi13 comparison goes into detail on exactly how much headroom each machine gives you for mixed VM and LXC workloads β€” useful reading if you are still in the hardware selection stage.

One thing I did not expect: adding Home Assistant actually reduced the number of browser tabs I keep open day-to-day. I used to have the Proxmox dashboard, Uptime Kuma, Navidrome, and Jellyfin each open in separate tabs. Now I have a single Lovelace dashboard that shows media playback state, service health via the Uptime Kuma integration, Zigbee device battery levels, and power consumption for each room. It is the unified view of my homelab I did not know I was missing until I had it.

Need help setting up your homelab?

I help individuals and small teams design and deploy Proxmox-based self-hosted infrastructure β€” from hardware selection to running services in production. Let's talk β†’

Ricardo Gil is a full-stack developer (.NET/Angular) with 6+ years of experience. He runs a personal homelab on a Beelink mini PC with Proxmox VE, self-hosting everything from Jellyfin to local LLMs with Ollama. More about Ricardo β†’
πŸ“¬Weekly Newsletter

Get the best home lab & AI content

No spam. One email per week. Unsubscribe anytime.

Share this article