Install Home Assistant OS with KVM on Ubuntu headless (CLI only)

Followed this guide quite a few times. First time it worked great, until I restarted my machine, VM didn’t come up automatically so I restarted it (and found a setting in virt-manager to start on boot) but, on restart the network settings were somehow screwy. I have no enp0s3 interface, but the interface in ha network info shows as such. and as many times as I try to kill the VM and restart from scratch, it always comes back as enp0s3 and I can no longer get connection.

You did create a bridge, and assign the Home Assistant OS VM to that bridge during the install, I assume (during sections 2 and 3 in the guide)?

Your bridge should be up. Check by (assuming your bridge is called br0): ifconfig br0. It should output something like this (at least saying UP, and showing a local IP on line 1 and 2, respectively):

br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet  netmask  broadcast
        inet6 fe80::221:5eff:fec6:4304  prefixlen 64  scopeid 0x20<link>
        ether 00:21:5e:c6:43:04  txqueuelen 1000  (Ethernet)
        RX packets 71078047  bytes 33733274513 (33.7 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 56093650  bytes 12627130431 (12.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

If it is, you can then check (and edit) your hassos.xml. Assuming you called the VM hassos:

virsh edit hassos

Take a look at the interface type section. Mine has:

    <interface type='bridge'>
      <mac address='REDACTED'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>

where the <source bridge='br0'/> means that it is using the bridge I created (br0). Assuming you have set up the bridge as described in section 2, you can just change this line to reflect that. If not working, you might need to restart the VM afterwards.

Would this method work with Raspberry Pi running KVM?

Pi appears to be able to run KVM virtualisation. But I sense there may be differences between a full x86 machine and ARM based Pi.

Absolutely no idea. If you try, please do report back, and I’ll add a note at the top.

However, that would probably be done more as a curiosity, since (1) you can just directly flash the Home Assistant OS for RPi (Raspberry Pi - Home Assistant) and (2) you probably can’t use the RPi for much else anyway.

The Pi (even the “mighty” RPi 4 with 8 GB RAM) has limited resources, you’d need a fairly simple setup to not see a bottleneck in RPi resources/performance just running Home Assistant, so adding the complexity of virtualization and other services (presumably you’d want to virtualize because you’d want it to run other things as well?), I’m afraid it would slow down Home Assistant more than many people would be willing to accept.

But as a curiosity, or for a very simple setup, I’d certainly encourage that you give it a go :slight_smile:

Just found this “Architecture Decision Record” that says only support “Virtual Machine (64 bits intel-based)”. So I think the answer would be “not possible on ARM based devices”.

I’m a one plug fits one socket kind of guy, everything is highly utilised and optimised with little to spare. HA cannot be offline leaving even lights non functional. I also don’t have spare Pi to test this with. So we can only go with the ADR information.

For me, as you said, I want to run other stuff. I have a few other very simple programs I’ve written before I adopted HA. I currently run HA Supervised. But they had very briefly considered scrapping support of Supervised method many moons ago, which leaves me uneasy. HA Analytics also shows low install base. So I figure it’s best to move to a definitely supported method. Just installing HA OS is too restrictive for me, I still want to run Linux as host system. Also don’t see point of powering 2 Pi’s when 1 can do the job adequately. Still searching for an ideal NUC that is as low power as a Pi and passively cooled.

None the less, when I do eventually get on 64bits Intel based machine for virtualisation. Headless KVM install would be my preferred method. So thank you for posting this guide.

Exactly why I wrote first the oVirt guide, then after the CentOS future took a dark turn, I turned to KVM on my current Ubuntu setup; I wanted to finally move away from my Home Assistant Container setup.

Though I must (shamefully) admit that a few complications (well, time constraints since I want to move ZigBee from DeCONZ to ZHA, and I have a lot of devices that need to be re-paired) means that I wrote the guides, and tested, but my main Home Assistant is still the container… I did tell my girlfriend that I wanted 48 hours undisturbed for my birthday, so let’s see!

Well, I hope you find something. Though my experience is that once the Home Assistant setup grows, an RPi quickly becomes insufficient, even if only running Home Assistant. So you might be better off looking at e.g. an Odroid. If you need x64, the H2+ is the way to go, though the Home Assistant Blue uses the N2+ (maybe because ARM typically uses less power?).

1 Like

Thanks for your guide! It’s great!
I’ve been having crazy problems with my networking.
I made a post about it here, so there is no point repeating.

If you could take a look, it would be greatly appreciated.

I’m still trying to figure out networking myself. I stuck with netplan for this guide because that was what I (finally) got working, so I’m not sure I’d be much help with ifupdown.

The only thing I noticed is that my ip route has no line mentioning eno1 (which would be enp2s0 for you). Mine shows:

default via dev br0 proto dhcp src metric 100 dev br0 proto kernel scope link src dev br0 proto dhcp scope link src metric 100 dev br-0ecd20e9f9fe proto kernel scope link src dev docker0 proto kernel scope link src linkdown dev br-993e33e0f597 proto kernel scope link src dev virbr0 proto kernel scope link src linkdown

But I’m not sure if it’s relevant, or what to do about it using ifupdown.

1 Like

Wow. Thanks for that.
Indeed, those routes got added when I started the HA vm.
Removing the enp2s0 routes did help the host to ping the gateway.

Now I need to work out why they are getting added by virsh (if added by this) and if stopping that happening will resolve the issue… what a pain!

BTW, your post helped lead me to my workaround.
I added metric 1000 to the bottom of my dhcpcd.conf which had an entry for enp2s0 .
This was adding the other routes!

It will still add them, but it will not hit them first

@Aephir what an awesome post. Very clear. This saved me loads of time and worked without issues on Ubuntu 20.04. Thanks so mcuh.

1 Like

@Aephir Thank you so much for this amazing post! I followed your guide and got it all set with a fresh install of Ubuntu 20.04. However, I had to change 1-2 things, I post them here in case anyone come across it.
In your guide Step 1.4, I believe these 2 commands are NOT required

gunzip hassos_ova-4.16.qcow2.gz
mv hassos_ova-4.16.qcow2 hassos.qcow2

Setting up Network Section
I had problems getting this to work, so I first had to “REMOVE” the default bridge created by KVM Install by running these 2 commands

virsh net-destroy default
virsh net-undefine default

Since I had “STATIC” IP for my Ubuntu, here is what my 00-installer-config.yaml looks like

    enh1: //This is going to be different for your setup
      dhcp4: false
      dhcp6: false
      interfaces: [ enh1 ] //whatever interface you have above
      addresses: [] //your static IP for the HOST (Ubuntu) 
      gateway4: // your router IP 
        addresses: [,] //Google Name Servers
        stp: true
        forward-delay: 4
      dhcp4: no
      dhcp6: no
  version: 2

you should do netplan generate first before applying to catch any errors

Step 3
The only thing I had to do is to install virt-install, if you run the command and get an error, it tells you what you need to do to install it.

Last in order for the KVM to start automatically, run this command
virsh autostart hassos //name of your VM you created

I changed the IP for Home Assistant from the SuperVisor UI. overall fantastic guide ! really appreciate the time effort you put towards this.

1 Like

Great, thanks for posting your experience and additions!

I think the qcow2 file you can download has been compressed in different ways over the months/years, so that part of the guide might be outdated. I think I half-updated the guide the last time (when it changed from .gz to .xz, but apparently didn’t update everything. Thanks, I have now (I hope) updated all of that :slight_smile:

I’ll add a link to your post in the guide for anyone having network issues.

1 Like

I just installed latest versions following your guide, and configured static ip on the bridge with exact configuration like @Raul_7

One more addition. For me, the homeassistant was not reachable as it didn’t have the ip address in the same subnet. Not sure whether it obtained ip before I set the ip on the bridge correct. But, I had to set static ip on hassos.

Set ip (else it generate unrechale ip):

virsh console hassos

nmcli con edit "Home Assistant OS default"
print ipv4 
set ipv4.addresses
set ipv4.dns
set ipv4.gateway

In my case, I choose this(ha) ip different from host ip created above with Netplan, but worked without any additional configuration on host.
hope that help someone.

Thanks for the hint on how to add a USB device.
In my case, I had to adjust the .xml slightly in format:

   <hostdev mode='subsystem' type='usb' managed='yes'>
        <vendor id='0x17ef'/>
        <product id='0x480f'/>

There is no more need for <devices>
I attached via this command: sudo virsh attach-device hassos --file usb_sticks.xml
The flag -persistent was not accepted when attaching

Hi all- I’m looking into setting up Home Assistant using the KVM image and, this might be a dumb question, but how much space is allocated to the Hassio when following this guide? My experience with VMs in the past has been to manually allocate a certain amount of space. Does KVM work differently?

Looking back at some notes I took when I first installed mine around 18 months ago or so, the disk image was around 6GB, and hassos thought it had a disk of about the same size and that about half of it was already used. I have over time expanded the image a couple of times using qemu-img resize.

Awesome- thank you for the quick reply!

Hi Gunnar,

I used --persistent (two --) not -persistent - you used only (one -) works and the USB Stick is up everytime I boot. I did this with Debian Bullseye 11 Headless.

Oops, autocorrect changed -- to . I’ve changed it in my previous post, thanks for catching this!