Tuesday, August 20, 2019

HomeAssistant in an LXD container

It's time to migrate my Home Assistant from it's experimental home in a Raspberry Pi to an LXD container on my Ubuntu server.

This has a lot of advantages, none of which are likely of the slightest interest to you. However, it also has one big problem: My Z-Wave USB dongle, currently plugged into the Pi, will need a new solution.

This blog post is about setting up Home Assistant in an LXD container. A different blog post will detail how to let the container see the USB dongle across the network

Preliminaries

First, the server needs to have LXD installed, and we need to create a container for Home Assistant.

In this case, I created a container called "homeassistant." It has a consistent IP address assigned by the LAN router (aa.bb.cc.dd), it has a user ("me") with sudo permission, and that user can ssh into the container. To the network it looks like a separate machine. To me, it behaves like a VM. To the host server, it acts like an unprivileged container.

Installing

First we install the python dependencies:

    me@homeassistant:~$ sudo apt-get update
    me@homeassistant:~$ sudo apt-get upgrade
    me@homeassistant:~$ sudo apt-get install python3 python3-venv python3-pip libffi-dev libssl-dev

Add a user named "homeassistant" to run the application. We need to add me to the new "homeassistant" group, so I can edit the config files.

    me@homeassistant:~$ sudo useradd -rm homeassistant -G dialout    // Create the homeassistant user and group
    me@homeassistant:~$ sudo adduser me homeassistant                // Add me to the homeassistant group
    me@homeassistant:~$ newgrp homeassistant                         // Add group to current session; no need to logout

Create the homeassistant directory in /srv, set the ownership, and cd into the dir

    me@homeassistant:~$ cd /srv
    me@homeassistant:~$ sudo mkdir homeassistant
    me@homeassistant:~$ sudo chown homeassistant:homeassistant homeassistant
    me@homeassistant:~$ cd /srv/homeassistant

Switch to homeassistant user, create the venv, install homeassistant:

    me@homeassistant:/srv/homeassistant $ sudo -u homeassistant -H -s
    homeassistant@homeassistant:/srv/homeassistant $ python3 -m venv .
    homeassistant@homeassistant:/srv/homeassistant $ source bin/activate
    (homeassistant) homeassistant@homeassistant:/srv/homeassistant $ python3 -m pip install wheel
    (homeassistant) homeassistant@homeassistant:/srv/homeassistant $ pip3 install homeassistant

First Run and Testing

Start Home Assistant for the first time. This takes a few minutes - let it work:

    (homeassistant) $ hass

Home Assistant should be up and running now. Try to login to the container's webserver (included with homeassistant). Remember how we assigned the container an IP address? (aa.bb.cc.dd) Let's use it now. From another machine on the LAN, try to connect with a web browser: http://aa.bb.cc.dd:8123. If it doesn't work, stop here and start troubleshooting. You can CTRL+C hass to stop it, or you can stop it from inside the web page.

Make Config Files

Once Home Assistant is working, let's change the permissions of the config files so that members of the "homeassistant" group (like me) can edit the files:

    (homeassistant) $ exit                                 // Exit the Venv
    homeassistant@homeassistant:/srv/homeassistant $ exit  // Exit the homeassistant user
    me@homeassistant:/srv/homeassistant $ cd ~             // Return to home dir - optional
    me@homeassistant:~$ sudo chmod 644 /home/homeassistant/.homeassistant/automations.yaml
    me@homeassistant:~$ sudo chmod 644 /home/homeassistant/.homeassistant/configuration.yaml
    me@homeassistant:~$ sudo chmod 644 /home/homeassistant/.homeassistant/groups.yaml
    me@homeassistant:~$ sudo chmod 644 /home/homeassistant/.homeassistant/scripts.yaml
    me@homeassistant:~$ sudo chmod 644 /home/homeassistant/.homeassistant/secrets.yaml

Let's link Home Assistant to systemd, so hass starts when the container comes up, and hass stops when the container goes down. (Reference):

    me@homeassistant:~$ sudo nano /etc/systemd/system/home-assistant@homeassistant.service

        [Unit]
        Description=Home Assistant
        After=network-online.target

        [Service]
        Type=simple
        User=homeassistant
        ExecStart=/srv/homeassistant/bin/hass -c "/home/homeassistant/.homeassistant"
        // No need for a 'stop' command. Systemd will take care of it automatically

        [Install]
        WantedBy=multi-user.target

    me@homeassistant:~$ sudo systemctl --system daemon-reload                       // Load systemd config changes
    me@homeassistant:~$ sudo systemctl enable home-assistant@homeassistant.service  // Or disable
    me@homeassistant:~$ sudo systemctl start home-assistant@homeassistant.service   // Or stop

Finally, a word about updates: Home Assistant updates frequently, and since it's not deb-based, unattended-upgrades cannot see it. However, starting the application will automatically download and install Home Assistant updates. When this occurs, the web page will take a full minute (or three) before appearing. Be Patient!

    me@homeassistant:~$ sudo -systemctl restart home-assistant@homeassistant.service  // Updates!

No comments: