Home Assistant VM (HAOS on ereshkigal)#
Home Assistant used to run on the HA Green appliance. In July 2026 that
appliance’s external USB data disk dropped out and the Supervisor wedged at
“waiting for the Home Assistant CLI to be ready” — a ~10 h outage that also
took down the MQTT broker, the tailnet subnet router, and IoT reachability,
because all of it lived on that one box. Home Assistant now runs as a Home
Assistant OS (HAOS) VM on ereshkigal, which is always-on, on real storage,
and borg-backed.
Because it’s a full HAOS VM (not HA Core), the encrypted appliance backup — with all ~19 add-ons (Matter, Node-RED, AdGuard, InfluxDB, Grocy + BarcodeBuddy, Music Assistant, Mosquitto, ESPHome, …) — restores 1:1.
Architecture#
| Piece | Value |
|---|---|
| Host | ereshkigal (libvirt/qemu, system connection) |
| Domain | haos — persistent, autostart enabled (reboot-safe) |
| Firmware / machine | UEFI (OVMF, default on 26.05) / q35 / swtpm |
| Resources | 2 vCPU, 4 GiB RAM |
| Disk | /dev/disk/by-uuid/434354c2-7991-4e02-afcc-6c17d25bd2fd (HAOS 18.1 OVA image on lvm) |
| LAN NIC | virtio, bridged to vmbr0 → 192.168.0.55 (took over the old appliance’s IP) |
| IoT NIC | virtio, bridged to br-iot → 192.168.2.55 (IoT VLAN, tag 3) |
| Radio | Nabu Casa Connect ZBT-1 (Zigbee/Thread) via VFIO passthrough of the whole 0000:41:00.0 USB controller (alone in IOMMU group 14) |
The declarative side lives in modules/nixos/virtualization/haos-vm.nix
(tsunaminoai.haosVm, enabled on ereshkigal). Creating/onboarding/restoring the
VM is interactive and is not in a nixos switch — see below.
Access#
- Web UI: http://192.168.0.55:8123
- Console (onboarding / recovery):
sudo virsh vncdisplay haoson ereshkigal, thenssh -L 5900:127.0.0.1:5900 ereshkigaland point a VNC client atlocalhost:5900. - HAOS CLI: the console
ha >prompt;logindrops to the host shell. virshneedssudoon ereshkigal (polkit blocks the system connection over non-interactive SSH).
Networking: the IoT-VLAN leg#
The VM is dual-homed. Its LAN leg (192.168.0.55) carries the default route,
DNS, and the frontend. Its IoT leg (192.168.2.55) lets IoT devices on
192.168.2.0/24 discover and reach HA (mDNS, direct connections).
On the host, haosVm.iotLeg peels VLAN 3 off the LAN trunk into an L2-only
bridge the VM attaches to — the host takes no IP on it, which is why this
avoids the exit-node policy routing and Tailscale table-52 precedence that would
otherwise fight a routed IoT leg:
bond1 (LAN trunk) ──┬── vmbr0 (untagged LAN, 192.168.0.20)
└── bond1.3 ──── br-iot ──── vnet (VM's 2nd NIC)
Requirements:
- Unifi: the switch port(s) for
bond1must trunk VLAN 3. (On the USW Pro 24 the ereshkigal LAG uses Tagged VLAN Management → Allow All, so this is already satisfied.) - VM NIC (persistent, once): the second NIC must have a fixed MAC or HAOS treats each re-attach as a new interface and its config won’t stick:
sudo virsh attach-interface --domain haos --type bridge \
--source br-iot --model virtio --persistent --live
- HAOS side: set the second adapter static, no gateway (keep the default
route on the LAN leg). Match it by MAC in
ha network info:
ha network update <iface2> --ipv4-method static --ipv4-address 192.168.2.55/24
Recovery / gotchas#
Things that bit us during the cutover — check these first:
- Frontend (
:8123) dead but the observer (:4357) is green → HA Core’shttpintegration failed to start, almost always becauseconfiguration.yamlpointsssl_certificate/ssl_keyat cert files that aren’t present. Comment those lines (vi /mnt/data/supervisor/homeassistant/configuration.yamlfrom the host shell) andha core restart, or restore the/sslfolder. - A hot-plugged NIC doesn’t show in
ha network info→ the Supervisor only enumerates interfaces at boot.core restart/net reloaddon’t re-scan. Reboot the VM (ha host reboot); the NIC is in the persistent config so it comes back and gets enumerated. - Keep the HA Green appliance powered OFF. It also claims
192.168.0.55statically — powering it on causes an IP conflict with the VM. - Do not plug anything into the NEC
0000:41:00.0controller on ereshkigal. The whole controller is VFIO-bound to the VM; anything on it vanishes into the guest (the LimeSDR was moved tomokoufor this reason). - Don’t let HAOS re-adopt an external USB “data disk.” That dependency is what caused the original outage; keep HA’s data on the VM’s virtual disk (borg backs up ereshkigal).
Rebuild from scratch#
- Deploy ereshkigal with
tsunaminoai.haosVm.enable = true(thehaos-vm-imageservice fetches + verifies the pinned HAOS image). haos-vm-installon ereshkigal — creates + autostarts the domain (with theradioPcicontroller passthrough).- Console in over VNC, onboard, restore the encrypted backup (enter the emergency-kit key). All add-ons + config come back.
- Add the IoT-leg NIC and configure it in HAOS (see Networking above).