OpenHAB Docker install feature

every time my docker gets updated I loose the installation of two features that I need to run an addon in the addons folder.
I need to manually go to the OpenHAB console ad install:
feature:install openhab-core-io-transport-mqtt
feature:install openhab-transport-serial

Can I somehow run a script or tell via the ENV variables that OpenHAB should install those two features when it gets updated?

I have not yet tested OH Docker. How are you updating?
If your userdata and configuration folders are outside the container I would not expect that to happen

the configs etc are outside of the docker in a separate folder and that works fine. However the two bindings listed above need to be installed via CLI and they are not reinstalled once I update the docker image
I use ouroboros to update the docker.

I am not familiar with that. Do you have a link handy?

1 Like

You need to mount both conf and userdata into the container. The installed add-ons will be preserved if you keep userdata outside the container too.

they are all outside the container but they are not preserved, probably since I need to install them via CLI an not over the Paper GUI. Is there a solution for that?

Hi i dont know much about docker but i have seen this config…
maybe it will help you

good luck…

thx but this is the “normal” config for a docker container so nothing special

Can you show the compose file or run command you use?

the run command:
‘gosu’ ‘openhab’ ‘tini’ ‘-s’ ‘./’

I use portainer to launch my containers here is the inspect file:

    "AppArmorProfile": "docker-default",
    "Args": [
    "Config": {
        "AttachStderr": false,
        "AttachStdin": false,
        "AttachStdout": false,
        "Cmd": [
        "Domainname": "",
        "Entrypoint": [
        "Env": [
        "ExposedPorts": {
            "1883/tcp": {},
            "5007/tcp": {},
            "8080/tcp": {},
            "8101/tcp": {},
            "8443/tcp": {}
        "Hostname": "openhab",
        "Image": "openhab/openhab:latest",
        "Labels": {
            "maintainer": "openHAB <>",
            "": "2020-01-21T00:16:41Z",
            "org.label-schema.description": "An open source, technology agnostic home automation platform",
            "org.label-schema.docker.dockerfile": "/Dockerfile",
            "org.label-schema.license": "EPL-2.0",
            "": "openHAB",
            "org.label-schema.url": "",
            "org.label-schema.vcs-ref": "60e02f3f7cfab88623f949b1ffca5f04f4db24db",
            "org.label-schema.vcs-type": "Git",
            "org.label-schema.vcs-url": "",
            "org.label-schema.vendor": "openHAB Foundation e.V.",
            "org.label-schema.version": "2.5.1"
        "OnBuild": null,
        "OpenStdin": false,
        "StdinOnce": false,
        "Tty": true,
        "User": "",
        "Volumes": {
            "/etc/localtime": {},
            "/openhab/addons": {},
            "/openhab/conf": {},
            "/openhab/userdata": {},
            "/tmp": {}
        "WorkingDir": "/openhab"
    "Created": "2020-01-21T11:47:54.652489462Z",
    "Driver": "overlay2",
    "ExecIDs": [
    "GraphDriver": {
        "Data": {
            "LowerDir": "/var/lib/docker/overlay2/f98189b9804f7c49fe99fbb81fd46563d4b48bbb36384c3a7fe7f3b1e2b6fad5-init/diff:/var/lib/docker/overlay2/6265384d91e90e06cc755e2b70214057b4eb9e7ba312bb2a979dad9828fbdf00/diff:/var/lib/docker/overlay2/1ff75eee2e313ff75317e086e2dbbb27c7221a6a3af8d3f5052c3d4a9c700e80/diff:/var/lib/docker/overlay2/1eda43b8b4c40d54f65f4b30fa041f8ca9bc56b26e983557ca0dd2ac308994e7/diff:/var/lib/docker/overlay2/88628cb73f79c0c83450f321a90a14d2fa45d5b298283ff45002e5738fdb5efb/diff:/var/lib/docker/overlay2/7fdf6d2715ed91fad6a69b16ceafe96284fb8e27b1ab48f9693d4cb281ba3d18/diff:/var/lib/docker/overlay2/a6b6156f42e7be8e9e0fe1c6014c75a6103ada82fc328908f550b7be89676671/diff:/var/lib/docker/overlay2/32011ae8fd0b1865e526959f785ebd5a282b5e010a55e397b4c9a37ab48364be/diff:/var/lib/docker/overlay2/a23dcc3296204e14ac222ee72fe7922fa69a80ae30eca30824d8e103254656b1/diff:/var/lib/docker/overlay2/0777b882737552c666d60d6566b523ca3db9913b616cbb7f2d1c695fd116f184/diff",
            "MergedDir": "/var/lib/docker/overlay2/f98189b9804f7c49fe99fbb81fd46563d4b48bbb36384c3a7fe7f3b1e2b6fad5/merged",
            "UpperDir": "/var/lib/docker/overlay2/f98189b9804f7c49fe99fbb81fd46563d4b48bbb36384c3a7fe7f3b1e2b6fad5/diff",
            "WorkDir": "/var/lib/docker/overlay2/f98189b9804f7c49fe99fbb81fd46563d4b48bbb36384c3a7fe7f3b1e2b6fad5/work"
        "Name": "overlay2"
    "HostConfig": {
        "AutoRemove": false,
        "Binds": [
        "BlkioDeviceReadBps": null,
        "BlkioDeviceReadIOps": null,
        "BlkioDeviceWriteBps": null,
        "BlkioDeviceWriteIOps": null,
        "BlkioWeight": 0,
        "BlkioWeightDevice": [],
        "CapAdd": [
        "CapDrop": [
        "Capabilities": null,
        "Cgroup": "",
        "CgroupParent": "",
        "ConsoleSize": [
        "ContainerIDFile": "",
        "CpuCount": 0,
        "CpuPercent": 0,
        "CpuPeriod": 0,
        "CpuQuota": 0,
        "CpuRealtimePeriod": 0,
        "CpuRealtimeRuntime": 0,
        "CpuShares": 0,
        "CpusetCpus": "",
        "CpusetMems": "",
        "DeviceCgroupRules": null,
        "DeviceRequests": null,
        "Devices": [
                "CgroupPermissions": "rwm",
                "PathInContainer": "/dev/ttyACM0",
                "PathOnHost": "/dev/ttyACM0"
        "Dns": [],
        "DnsOptions": [],
        "DnsSearch": [],
        "ExtraHosts": null,
        "GroupAdd": null,
        "IOMaximumBandwidth": 0,
        "IOMaximumIOps": 0,
        "IpcMode": "shareable",
        "Isolation": "",
        "KernelMemory": 0,
        "KernelMemoryTCP": 0,
        "Links": null,
        "LogConfig": {
            "Config": {},
            "Type": "json-file"
        "MaskedPaths": [
        "Memory": 0,
        "MemoryReservation": 0,
        "MemorySwap": 0,
        "MemorySwappiness": null,
        "NanoCpus": 0,
        "NetworkMode": "my-net",
        "OomKillDisable": false,
        "OomScoreAdj": 0,
        "PidMode": "",
        "PidsLimit": null,
        "PortBindings": {
            "8080/tcp": [
                    "HostIp": "",
                    "HostPort": "8080"
            "8101/tcp": [
                    "HostIp": "",
                    "HostPort": "8101"
            "8443/tcp": [
                    "HostIp": "",
                    "HostPort": "8444"
        "Privileged": false,
        "PublishAllPorts": false,
        "ReadonlyPaths": [
        "ReadonlyRootfs": false,
        "RestartPolicy": {
            "MaximumRetryCount": 0,
            "Name": "always"
        "Runtime": "runc",
        "SecurityOpt": [
        "ShmSize": 67108864,
        "UTSMode": "",
        "Ulimits": null,
        "UsernsMode": "",
        "VolumeDriver": "",
        "VolumesFrom": null
    "HostnamePath": "/var/lib/docker/containers/a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf/hostname",
    "HostsPath": "/var/lib/docker/containers/a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf/hosts",
    "Id": "a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf",
    "Image": "sha256:823f30d1ac740cc89a548ae5d7f7ae19d1a05ffc23de06786f3bb61cdc781b6c",
    "LogPath": "/var/lib/docker/containers/a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf/a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf-json.log",
    "MountLabel": "",
    "Mounts": [
            "Destination": "/tmp",
            "Mode": "",
            "Propagation": "rprivate",
            "RW": true,
            "Source": "/tmp",
            "Type": "bind"
            "Destination": "/etc/localtime",
            "Mode": "ro",
            "Propagation": "rprivate",
            "RW": false,
            "Source": "/etc/localtime",
            "Type": "bind"
            "Destination": "/openhab/addons",
            "Mode": "",
            "Propagation": "rprivate",
            "RW": true,
            "Source": "/sharedfolders/AppData/openhabMile/addons",
            "Type": "bind"
            "Destination": "/openhab/conf",
            "Mode": "",
            "Propagation": "rprivate",
            "RW": true,
            "Source": "/sharedfolders/AppData/openhabMile/conf",
            "Type": "bind"
            "Destination": "/openhab/userdata",
            "Mode": "",
            "Propagation": "rprivate",
            "RW": true,
            "Source": "/sharedfolders/AppData/openhabMile/userdata",
            "Type": "bind"
    "Name": "/openhab",
    "NetworkSettings": {
        "Bridge": "",
        "EndpointID": "",
        "Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "HairpinMode": false,
        "IPAddress": "",
        "IPPrefixLen": 0,
        "IPv6Gateway": "",
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "MacAddress": "",
        "Networks": {
            "my-net": {
                "Aliases": [
                "DriverOpts": null,
                "EndpointID": "a0c1a735fec1184b98068bcc45ea42b535378fe012bde23755e0fae0eb94ac5f",
                "Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAMConfig": {},
                "IPAddress": "",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "Links": null,
                "MacAddress": "02:42:ac:12:00:0a",
                "NetworkID": "f513434f5b46a7ca9303b5956945250bcaae791ee6d8c01373b85ee4655e53da"
        "Ports": {
            "1883/tcp": null,
            "5007/tcp": null,
            "8080/tcp": [
                    "HostIp": "",
                    "HostPort": "8080"
            "8101/tcp": [
                    "HostIp": "",
                    "HostPort": "8101"
            "8443/tcp": [
                    "HostIp": "",
                    "HostPort": "8444"
        "SandboxID": "edc5698bd650001c87f7c3ba320e41ed49c74537b94fd546c801872f577f7943",
        "SandboxKey": "/var/run/docker/netns/edc5698bd650",
        "SecondaryIPAddresses": null,
        "SecondaryIPv6Addresses": null
    "Path": "/",
    "Platform": "linux",
    "Portainer": {
        "ResourceControl": {
            "Id": 50,
            "ResourceId": "a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf",
            "SubResourceIds": [],
            "Type": 1,
            "UserAccesses": [],
            "TeamAccesses": [],
            "Public": false,
            "AdministratorsOnly": true,
            "System": false
    "ProcessLabel": "",
    "ResolvConfPath": "/var/lib/docker/containers/a87d7a9f029ee7a4dec13fbf044bc18dafa9f9fa5a1e0d9f1255c70367c5dcaf/resolv.conf",
    "RestartCount": 0,
    "State": {
        "Dead": false,
        "Error": "",
        "ExitCode": 0,
        "FinishedAt": "2020-01-21T13:53:41.397479818Z",
        "OOMKilled": false,
        "Paused": false,
        "Pid": 32286,
        "Restarting": false,
        "Running": true,
        "StartedAt": "2020-01-21T13:53:42.14846879Z",
        "Status": "running"

If your userdata is correctly mounted to a folder outside your container, you should place the .jar files of the bindings you don’t install in PaperUI in the userdata/addons folder.
This way the binding will be loaded with every new version without a manual install.

I think (can be wrong) that the manual cli-install will install a binding in the same way as PaperUI so they will be lost with an upgrade.

I have one binding in the Addons folder and that works great. however the two bindings: that I listed (openhab-core-io-transport-mqtt, openhab-transport-serial) don’t come with a Jar file therefore I need to install them via the CLI. If installed via CLI they a re definitely lost thats why I ask if there is a possibility to automatically install them after an upgrade / update fo the docker file
Or do you know where I can find a JAR file of the two bindings that I need to install via feature install…

Indeed. The volume config looks ok. Adding the .jar files to the addons folder should do the trick. Not sure why that is needed to survive an upgrade.

Alternatively you could also try to add them to a minimal addons.cfg instead of adding the .jar files that will not get automatically updated.

1 Like

Installing them via the CLI or PaperUI is identical. They get installed to userdata. There is nothing special about the fact that you are running in Docker if you are preserving userdata as well as conf.

When ever you create a new container with a different version than what the stuff in userdata indicates it was created with, the entrypoint script will clear the cache and tmp folders. But that’s the same thing that happens when you upgrade a regularly installed OH.

The fact you are running in a container is irrelevant. It’s the upgrade, and more importantly the clearing of the cache that is making the bundles go away. The root problem is when you install an addon by plopping it’s jar file into the addons folders, the other bundles it depends upon like the two you are listing do not get installed automatically. These two bundles are not bindings, they are services used by bindings.

One thing you can do is install some bindings that do depend on those. I know that Zwave depends on serial and obviously MQTT depends on the mqtt bundle.

I may be missing something, but I haven’t seen the solution I use. To make binding adding stick, I add them to the services.conf file. I install a binding for the first time through the UI, then I watch the log to see the actual binding name and section used within openhab. I take that name, put it in the right section in services.conf, and the next time I recreate the container the binding is there.

How does ouroboros compare with watchtower for updating docker ?

watchtower is somehow dead and outdated. With ouroboros you can customize much more and is easier to setup.

ok I somehow figured it out.
I now installed the two bindings via the Paper UI instead of the CLI. And today I got an email from ouroboros that OpenHAB has been updated. As I connected to the openHAB interface I saw that everything is running as excepted and also the two bindings were still installed.
So at least for me it looks like that installing over the CLI somehow puts the bindings into a temp folder that gets wiped once an upgrade of the OpenHAB is installed. And installing it over the PaperUI save it to the userdata that does not get wiped…

How often/under what circumstances do you guys let watchtower or ouroboros update openhab docker?