You need some packages from pip (In that case you need your own venv for graalpy initialized- as described in the documentation of the automation)
You run OpenHAB in a container
Problem
The naive way to add the venv is to prepare it in the userdata folder from some other machine (i.e. the host running the container) as described in the documtation, in addition to that also the graalpy directoy needs to be mounted into the container with the same path (as the venv uses symlinks to it).
Initially this approach worked fine but I discovered the following issues:
“patchelf” seems not to be “so optional” - I had multiple errors that rules couldn’t be loaded as patchelf was not found (and patchelf is not installed in the official openhab images)
I looked for a solution that could avoid manual manipulation of the userdata folder when a new OH instance get’s deployed - i.e. if I need to setup a fresh OH instance for testing.
Solution
To solve this issues I decided to built my own OH docker image based on the official OH image. This image basically adds the following stuff to the official image:
install patchelf
download graalpy and add it to the container
initialize a venv on container startup in the userdata folder (if not there already)
In addition I also added some automated tests to ensure that with that image the python automation can be used with external packages installed via pip without additional tweaks.
It’s been a long time since I’ve done anything with Python and OH but I’m surprised by setting the venv in the userdata folder. I would have expected it to be in the conf folder, specifically conf/automation/python. Is there a reason to put it in userdata?
An alternative approach to building a new image would be to create a shell script that does all these steps and mount it to /etc/cont-init.d. All the scripts found there get executed when the container starts up before openHAB is launched.
yeah I also wondered about the location in the userdata but it seems to be the default one (also described in the documentation Python Scripting - Automation | openHAB)
The idea with cont-init.d is also a good one - might also be much simpler …
The user home folder is userdata so that might be it. But there is no requirement to put a venv in the home folder.
The downside of cont-init.d is depending on what the scripts do it can add a good bit of time to the starting of the container, particularly with a new container. I have one such script that installs ffmpeg which has a ton of other packages so that first start after an upgrade is excruciatingly long.
I just wanted to point out that there is an alternative for those who may not want to build a custom image or use an unofficial image for some reason.
Great discussion — and @rlkoshak, your cont-init.d suggestion was spot on.
I forked Christian’s image and took a slightly different direction that works better for my Kubernetes
setup where the cache volume is ephemeral. The key difference: the GraalPy download and venv creation happen at image build time, not at container start.
With the original approach, every fresh pod start triggers a full GraalPy download and venv
initialization — which can take several minutes. Moving this into the build means container startup is
reduced to placing a single symlink, regardless of how often pods are recreated.
Two further additions:
Auto-detection of the GraalPy version — a first build stage extracts the version directly from
the org.graalvm.python.python-language-*.jar bundled in the openHAB addons KAR. No manual version lookup, no hardcoding. Changing BASE_IMAGE is the only thing needed for an update, which makes it fully Renovate-driven.
Weekly CI — a GitHub Actions workflow fetches all stable openHAB 5.x release tags from Docker Hub every Sunday and builds each one as a matrix job, pushing to GHCR automatically.