Introduction Link to heading
When I originally published instructions on installing Home Assistant Core into a FreeBSD jail, I did not allow for the fact that Python and Home Assistant Core would need to be upgraded in the future. In the original instructions I:
- used pyenv to install a version of Python,
- created a virtual environment with that version of Python, and
- installed and ran Home Assistant core from that Python virtual environment.
This is fine and I should be able to upgrade Home Assistant, but what if I need to:
- upgrade my version of Python? or
- roll back to the previous version of Home Assistant?
What I wanted to see was whether or not I could manually upgrade and downgrade Python and Home Assistant and still have a working HA instance.
Here be dragons!
You are responsible for taking snapshots and backups before you do any upgrades or downgrades.
One day, an upgrade may introduce a breaking change that stops you going back a version. Or an upgrade to a plugin may not work on a previous version of HA or Python. These steps worked for me when I went back one release of HA or Python with no extra plugins installed. I provide no assurances nor any guarantees that this will work for you.
If it breaks, you will need to glue both pieces back together.
Preparing the jail Link to heading
The idea here is to set up the jail, install dependencies, and create the homeassistant
user once.
Creating the jail Link to heading
First we create the jail:
host # bastille create -V home-assistant-test 14.0-RELEASE "DHCP SLAAC" igb0
host # bastille console home-assistant-test
I prefer to use VNET jails so that I can assign IP addresses later.
Installing dependencies in the jail Link to heading
jail # pkg update
jail # pkg install \
ca_root_nss \
cmake \
curl \
git \
openblas \
openjpeg \
pkgconf \
pyenv \
rust \
sqlite3 \
vim
Create the homeassistant
user in the jail
Link to heading
jail # pw useradd homeassistant -w no -m -c "Home Assistant"
jail # pw groupmod dialer -m homeassistant
jail # chmod 770 /home/homeassistant
jail # pw usermod homeassistant -s /usr/local/bin/bash
I prefer to use bash as my shell and the rest of the commands assume that you are also using bash.
All commands from here onwards are run in the jail.
Installing Python using pyenv
Link to heading
These instructions are taken from decuser over at the FreeBSD forums
We need to switch to the homeassistant
user and install Python using pyenv.
We’re going to install the previous version of Python (at the time of writing: 3.11.7) so that we can upgrade it later.
# su - homeassistant
$ pyenv install 3.12.2
$ pyenv global 3.12.2
$ pyenv init
# Load pyenv automatically by appending
# the following to
# your shell's login startup file (for login shells)
# and your shell's interactive startup file (for interactive shells) :
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Restart your shell for the changes to take effect.
You will have to add the following lines to ~/.bashrc
and ~/.profile
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
Finally, we leave the homeassistant
use shell and switch back into it to check that pyenv
has loaded its shims correctly:
$ exit
# su - homeassistant
$ echo $PATH
/home/homeassistant/.pyenv/shims:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/home/homeassistant/bin
$ python --version
Python 3.12.2
Managing versions of Home Assistant Link to heading
We’re going to install each release of Home Assistant into its own Python virtual environment (PVE). In other words, 2023.12 will be in one environment, 2024.1 will be in another environment, and so on. These PVEs use the same version of Python, but will be separate from each other. This will let us upgrade to new point releases of HA within the same PVE, and let us test the next release of HA by creating a new PVE.
Creating a virtual environment for one release of Home Assistant (e.g. 2023.12) Link to heading
We’re going to install an old version of Home Assistant so that we can upgrade it later. For this example, I’m going to start with 2023.12
$ mkdir HA-2023.12
$ cd HA-2023.12/
$ python -m venv .
$ source bin/activate
If all went well, the shell prompt now begins with:
(HA-2023.12) $
This indicates that the HA-2023.12
environment is being used.
We update pip
and install wheel
:
$ pip install --upgrade pip
$ pip install wheel
There are a few a few dependencies that are not installed automatically when we use pip to install Home Assistant (python-zlib-ng
, numpy
, webrtc-noise-gain
).
The instructions for installing these are described here.
For 2023.12
I also had to manually install botocore
:
$ pip install git+https://github.com/boto/botocore
Now, let’s install and run 2023.12.1
:
$ pip install homeassistant==2023.12.1
$ hass --ignore-os-check --verbose
After a while, we’re greeted by the starting page:
Once we’ve set up a dummy user, we can see that were running 2023.12.1:
We also have a new folder in the homeassistant
user’s home directory:
$ ls -lah
drwxr-xr-x 7 homeassistant homeassistant 19B Feb 22 07:52 .homeassistant
Upgrading to a later point release of Home Assistant (e.g. 2023.12.1 -> 2023.12.3) Link to heading
This is very easy to do inside the Python virtual environment. All you need to do is use pip to install the next point release of HA:
$ pip install -U homeassistant~=2023.12.1
Installing collected packages: homeassistant
Attempting uninstall: homeassistant
Found existing installation: homeassistant 2023.12.1
Uninstalling homeassistant-2023.12.1:
Successfully uninstalled homeassistant-2023.12.1
Successfully installed homeassistant-2023.12.3
Upgrading to a later release of Home Assistant (e.g. 2023.12 -> 2024.1) Link to heading
When a new version of HA is released, we want to keep the old PVE intact and create a new PVE for the new version of HA.
There’s nothing to stop you upgrading to a new release of HA in a single PVE.
For example, you may have created a single PVE called homeassistant
and upgrade to a new release of HA in that PVE.
I run separate PVEs so that I can leave the old PVE and HA instance up and running while I’m getting the new release installed. This lets me fix up any missing dependencies and build errors before taking HA offline while I switch to the new version.
To do this, I’m going to log into a new shell in the jail and confirm that we’re still using the same version of Python:
$ which python
/home/homeassistant/.pyenv/shims/python
$ pyenv versions
* 3.12.2 (set by /home/homeassistant/.pyenv/version)
$ python --version
Python 3.12.2
I’m using a new shell because I don’t want to disrupt the already running HA instance.
First, we create a new Python virtual environment for Home Assistant Core 2024.1
:
$ mkdir HA-2024.1
$ cd HA-2024.1
$ python -m venv .
$ source bin/activate
$ pip install --upgrade pip
$ pip install wheel
Second, we have to install the manual dependencies just like we did earlier.
Finally, we install Home Assistant Core 2024.1
:
$ pip install homeassistant~=2024.1.0
If you have HA running in another shell, you will need to stop your previous HA instance before you start the new one.
$ hass --ignore-os-check --verbose
When we go to the HA web page now, we’re greeted by a login page, not the getting started page.
Once we log in with the previously created user, we can see that everything works fine and is now running 2024.1
:
Downgrading to a previous release of Home Assistant (e.g. 2024.1 -> 2023.12) Link to heading
What if something wasn’t working with 2024.1.1
and we wanted to go back to 2023.12.3
?
Assuming that we’re still in the HA-2024.1
PVE, all we need to do is deactivate
the current HA-2024.1
PVE and activate the HA-2023.12
PVE and restart hass
:
$ deactivate
$ source HA-2023.12/bin/activate
$ hass --ignore-os-check --verbose
And we can log in as usual.
I was able to switch between 2023.12
and 2024.1
with ease.
I could update the Lovelace dashboard in one version of HA and have it look exactly the same when I changed version of HA.
Recap: Managing Home Assistant versions Link to heading
So far, what we’ve done is create new PVEs for each minor version of HA (e.g. one for 2023.12
and another for 2024.1
).
Within each PVE, we use pip to upgrade the point release of HA (e.g. from 2023.12.1
to 2023.12.3
).
We can create a new PVE and switch to that PVE when we want to upgrade to a new HA release (e.g. going from 2023.12
to 2024.1
).
But eventually, we’re going to need to upgrade Python.
Managing Python versions Link to heading
Upgrading Python (e.g. 3.11 -> 3.12 OR 3.12.0 -> 3.12.1) Link to heading
Home Assistant regularly updates the minimum supported version of Python. I can’t find a link to where I read about the minimum supported Python version, but from memory, HA will only work with the stable releases of Python (also reported as bugfix releases). This means that you will need to update your version of Python at least every two years - but you are diligent enough to keep ot up to date aren’t you?
Installing a new version of Python is done via pyenv
:
$ pyenv versions
* 3.12.1 (set by /home/homeassistant/.pyenv/version)
$ pyenv install 3.12.2
$ pyenv global 3.12.2
$ pyenv versions
3.12.1
* 3.12.2 (set by /home/homeassistant/.pyenv/version)
This does not update the version of Python being used by the PVEs that you’ve already created.
You will need to create new PVEs based on the newly installed version of Python.
$ mkdir HA-2024.1.2
$ python -m venv .
$ source bin/activate
(HA-2024.1.2) $
$ which python
/usr/home/homeassistant/HA-2024.1.2/bin/python
$ python --version
Python 3.12.2
The rest of the HA install process is exactly the same as we have done previously, so I won’t repeat the steps here.
Going back to the previous version of Python (e.g. 3.12 -> 3.11) Link to heading
What if you are very diligent in keeping Python up to date, but for some reason a plugin doesn’t work with a newer version of Python? If you still have the old PVE, you may be able to simply deactivate the current PVE, activate the previous PVE, and be back up and running.
(HA-2024.1.2) $ deactivate
$ source HA-2024.1/bin/activate
(HA-2024.1) $ hass --ignore-os-check --verbose
Recap: Managing Python versions Link to heading
The process of upgrading Python is very straight forward.
Install a new version using pyenv
and then create a new PVE for HA.
You may decide to upgrade Python when you upgrade to a new release of HA because you are already creating a new PVE.
Going back a version of Python is also easy, just reactivate the old PVE.
Summary Link to heading
I hope you’ve found this a helpful suggestion on how to manage Home Assistant and Python virtual environments in a FreeBSD jail. This is probably not the only, or necessarily the best, way to manage the upgrades to HA. I wrote this up because, for my purposes, this works well.
Credits Link to heading
Thanks to @jan@jit.social for noticing that I had not listed ca_root_nss
as a dependency.