Upgrading Home Assistant – painless updates via docker-compose

Published by Oliver on

Setting up your own smarthome server with HomeAssistant and more is easy with Docker(-compose). Upgrading Home Assistant to keep everything up to date afterwards can be a challenge though. Here I will show a couple of ways to quickly update your containers.

A smarthome server based on Docker

My personal smarthome server setup heavily relies on Docker and docker-compose. It makes installation quite simple, allows you to quickly connect different services together and takes care of all the needed dependencies. If you just set it up once according to my GitHub repository you will forever run the exact same version of the software though. On the first startup docker will download the current image according to your docker-compose.yml file and then use that to create a container.

Fortunately updating containers via docker can also be pretty simple but there are a couple of things you need to keep in mind. I recently updated my own server which showcased a couple of different ways to do that. So I decided to share that here.

Upgrading Home Assistant and other software via Docker

Before you actually update anything you should think about two things: first do you even need to update? “Never change a running system” might actually be a good guideline in some cases. If the software is working well and has no access to any external systems you might not need to update it at all. If there are new features you are looking to use or the software is connected to the Internet on the other it might be a very good idea to keep it up to date.

Secondly you need to think about the application data. Any software you run via docker runs in a docker container. Such a container is a temporary construct built from a so called image. This image will never be changed. If you want to update your software you simply have to get a newer image.

This means whenever you stop a container it is gone. When you start it again it is recreated from the same (or another one you defined) image. All of this means that any data added to your container (that means data created by you or the application during runtime) is lost when you stop the container, unless you save it somewhere else.

To save data you usually use either docker volumes or (like I did) synchronize a part of your host system with the docker container. For example I do not want to loose my HomeAssistant configuration at every restart so I synched that directory with a data directory on my host system. You can find the configuration for that in the compose yaml file here. Make sure your data is safe before you upgrade!

Automatic updates

If you always want to keep most of your containers up to date there is a convenient solution called watchtower. I described the process in depth in my watchtower article. Basically this is another docker container that regularly scans all your running containers, pulls updates and restarts them.

As we all know with great power comes great resposibility though: automatic updates can also automatically break your setup! I only use this for smaller services that are not critical. Others like HomeAssistant and my Unifi-controller software I only upgrade manually. This can be done by adding a certain label to them. Here is an example for HomeAssistant.

Manually upgrading via docker-compose

The actual manual update for docker containers is pretty simple. Tell docker to pull the newest image and restart the container based on the new image. Find the compose file with the containers you want to update and run these commands:

docker-compose -f smarthome pull // get the newest images
docker-compose -f smarthome up -d // restart all containers that have new images
docker-compose -f smarthome logs -f homeassistant // check for example the logs for the homeassistant container to find any problems

Update: if you are using newer versions of the PI OS and Docker the compose syntax has changed from using docker-compose to docker compose. The rest of the commands will stay the same.

I did just that for my HomeAssistant container. It takes a moment to load the new images and then a couple of seconds to restart all of them. In my case it found a couple of minor updates and a new version of Home Assistant.

upgrading home assistant by pulling new images via docker-compose
Pulling updated images via docker-compose

This is where “never change a running system” was very true again: after updating the container did not start up again. I checked the logs and found this error:

Fatal Python error: pyinit_main: can't initialize time

Fortunately some quick search found a solution for that in the linuxserver FAQs. A new version of the libseccomp2 library is required which my system did not have installed (and Apt update did not help either). The suggested solution of installing the backport repository worked though. This is the code I ran but check the FAQ to get the newest version.

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138
echo "deb http://deb.debian.org/debian buster-backports main" | sudo tee -a /etc/apt/sources.list.d/buster-backports.list
sudo apt update
sudo apt install -t buster-backports libseccomp2

I am always using the newest version of the homeassistant/raspberrypi4-homeassistant image but only update manually from time to time. If you want to be on the safer side you need to understand how docker-compose determines which image to use. The creator of the image will upload new images to the docker-hub. By default each image will just be stored with its name and docker will always use the latest one.

To avoid that you can use so called tags. By default docker uses latest which is always the newest version but the creator can also maintain other versions of his software by using additional tags. Usually there will be one for each major version and possibly other branches like development in addition to latest.

You can always pin your container to a certain versions with such a tag. You could for example use stable or a certain version like 2021.7.4 for the Home Assistant container. If you want to use anything else but latest you have to add it to the image in your docker-compose file like

... 
homeassistant:
    container_name: homeassistant
    restart: unless-stopped
    image: homeassistant/raspberrypi4-homeassistant:2021.7.4 <- tag
...

Now this container will always use the newest 2021.7.4 version image of Home Assistant. It might also be updated but you will not get newer versions. This can be a very powerful feature for you to still get minor updates but do major ones manually.

Upgrade by changing tags

I do this for another one of my services: the unifi-controller software. This is essentially the heart of my network. A couple of weeks ago I still had this on automatic updates via watchtower. It pulled a new version with some problem resulting in a failed startup. Without that most of my network was down so I had a hard time fixing this. Afterwards I decided to only do manual major updates.

I fixed the image as image: ghcr.io/linuxserver/unifi-controller:arm32v7-version-6.2.25. Updating this is also very simple. After reading about some users running this version without a problem I just opened the hosting.yml file and edited this line to arm32v7-version-6.2.26. Then running pull and up like described above will update this container. This time without a problem 🙂

Categories: HomeAssistantBasics