Executing command via SSH from openhab inside docker with private key

Hello,

I’m running OH 2.1 in a docker container.

I want to power off my NAS when a switch is switched off. I guess I have use the exec binding for this, right?

Then, in the default dockerhub image, there of course is no ssh client. When I install it inside the docker container, where do I put the private key from my NAS so it is accessible to openhab when openhab is calling ssh commands

Running inside container:

ssh-copy-id -i .ssh/id_rsa.pub admin@nas

And adding a switch

Switch NAS “NAS [MAP(en.map):%s]” (Network) { nh=“nas”, exec=“OFF:sudo ssh -i ~/.ssh/id_rsa admin@nas shutdown -p now”}

Would this be the right way to do it?

Did you write a new Dockerfile and create a new image? This is the correct way to do this. Otherwise you will need to manually reinstall the ssh client every time the container is recreated. Docker containers are intended to be ephemeral.

So, since they are supposted to be ephermeral, you should mount the files needed by the container that should be persisted across multiple instances of the containers as volumes. So you should create your .ssh folder with the ownership and correct permissions for the userid of openhab inside the container (9001 byt default I think). Then mount this .ssh folder on your host to /openhab/.ssh in the container.

To summarize the correct way to do it is:

  1. Dreate a Dockerfile that uses the official openHAB Image as the base and installs the ssh client
  2. Build a new Image using this Dockerfile
  3. Create the needed .ssh folder and files somewhere on the host with ownership and proper permissions for user id 9001.
  4. Along with userdata and conf, mount this .ssh folder as a volume when you create and run the container to /openhab/.ssh.

You should really upgrade. There are lots of errors that existed in 2.1 that have been long since fixed.

I was facing a lot of issues when trying to upgrade to a new openhab docker image. First of all being the config files etc. not accessible to the user running openhab inside the container when mounting them to the right places.

A vanilla openhab 2.2 or 2.3 container didn’t even start up on its own because of this error:

+ test -t 0
+ [ 0 -eq 1 ]
+ set -euo pipefail
+ IFS=

+ [ limited = unlimited ]
+ rm -f /openhab/runtime/instances/instance.properties
+ rm -f /openhab/userdata/tmp/instances/instance.properties
+ NEW_USER_ID=9001
+ echo Starting with openhab user id: 9001
Starting with openhab user id: 9001
+ id -u openhab
+ echo Create user openhab with id 9001
Create user openhab with id 9001
+ adduser -u 9001 -D -g  -h /openhab openhab
+ ls -A /openhab/userdata
+ [ -z cache
config
etc
logs
tmp ]
+ cmp /openhab/userdata/etc/version.properties /openhab/userdata.dist/etc/version.properties
+ [ ! -z ]
+ ls -A /openhab/conf
+ [ -z html
icons
items
persistence
rules
scripts
services
sitemaps
sounds
things
transform ]
+ chown -R openhab:openhab /openhab
+ exec su-exec openhab ./start.sh
Launching the openHAB runtime...

                          __  _____    ____
  ____  ____  ___  ____  / / / /   |  / __ )
 / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __  |
/ /_/ / /_/ /  __/ / / / __  / ___ |/ /_/ /
\____/ .___/\___/_/ /_/_/ /_/_/  |_/_____/
    /_/                        2.3.0
                               Release Build

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown openHAB.

Error executing command: java.io.IOException: Unable to parse columns

I run the container with the following command line:

docker run --name openhab --tty \
 -v /etc/localtime:/etc/localtime:ro \
 -v /etc/timezone:/etc/timezone:ro \
 -v openhab_addons:/openhab/addons \
 -v openhab_conf:/openhab/conf \
 -v openhab_userdata:/openhab/userdata \
 -d \
 --restart=always \
 -e "OPENHAB_HTTP_PORT=8080" \
 -p 8080:8080 \
 openhab/openhab:2.3.0-armhf-alpine

However, when I run it with the following command, I don’t get the error but I also don’t have openhab available from the network:

docker run --name openhab --net=host --tty \
 -v /etc/localtime:/etc/localtime:ro \
 -v /etc/timezone:/etc/timezone:ro \
 -v openhab_addons:/openhab/addons \
 -v openhab_conf:/openhab/conf \
 -v openhab_userdata:/openhab/userdata \
 -d \
 --restart=always \
openhab/openhab:2.3.0-armhf-alpine

You should use the run command described on the README.

docker run \
        --name openhab \
        --net=host \
        --tty \
        -v /etc/localtime:/etc/localtime:ro \
        -v /etc/timezone:/etc/timezone:ro \
        -v openhab_addons:/openhab/addons \
        -v openhab_conf:/openhab/conf \
        -v openhab_userdata:/openhab/userdata \
        -d \
        --restart=always \
        openhab/openhab:2.3.0-amd64-debian

You should use --net=host or you need to export ALL of OH’s ports, not just 8080.

All the files mounted into the container under /openhab need to be owned by and have read write permissions for user 9001.

Do you have any logs from OH?

You should only use the armhf-alpine if you are running on an SBC like an RPi.

I’m indeed on a RPi 3. I will try the command from the documentation again

docker run \
 --name openhab \
 --net=host \
 --tty \
 -v /etc/localtime:/etc/localtime:ro \
 -v /etc/timezone:/etc/timezone:ro \
 -v openhab_addons:/openhab/addons \
 -v openhab_conf:/openhab/conf \
 -v openhab_userdata:/openhab/userdata \
 -d \
 --restart=always \
 openhab/openhab:2.3.0-armhf-alpine

Leads to this output in docker logs -f openhab

+ test -t 0
+ [ 0 -eq 1 ]
+ set -euo pipefail
+ IFS=

+ [ limited = unlimited ]
+ rm -f /openhab/runtime/instances/instance.properties
+ rm -f /openhab/userdata/tmp/instances/instance.properties
+ NEW_USER_ID=9001
+ echo Starting with openhab user id: 9001
Starting with openhab user id: 9001
+ id -u openhab
+ ls -A /openhab/userdata
+ [ -z cache
config
etc
logs
tmp ]
+ cmp /openhab/userdata/etc/version.properties /openhab/userdata.dist/etc/version.properties
+ [ ! -z ]
+ ls -A /openhab/conf
+ [ -z html
icons
items
persistence
rules
scripts
services
sitemaps
sounds
things
transform ]
+ chown -R openhab:openhab /openhab
+ exec su-exec openhab ./start.sh
Launching the openHAB runtime...

                          __  _____    ____
  ____  ____  ___  ____  / / / /   |  / __ )
 / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __  |
/ /_/ / /_/ /  __/ / / / __  / ___ |/ /_/ /
\____/ .___/\___/_/ /_/_/ /_/_/  |_/_____/
    /_/                        2.3.0
                               Release Build

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown openHAB.

Error executing command: java.io.IOException: Unable to parse columns

And who owns all the files in userdata and conf that you mount as volumes into the container? What do you see when you run ls -l on the host of those folders?

I don’t mount any folders, so docker creates named volumes:

The files inside are owned by:

root@raspberrypi:~# ls -al /var/lib/docker/volumes/openhab_conf/_data/
total 52
drwxrwxr-x 13 runningindocker runningindocker 4096 Jun 15 20:52 .
drwxr-xr-x  3 root            root            4096 Jun 15 20:52 ..
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 html
drwxrwxr-x  3 runningindocker runningindocker 4096 Jun 15 20:52 icons
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 items
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 persistence
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 rules
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 scripts
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 services
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 sitemaps
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 sounds
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 things
drwxrwxr-x  2 runningindocker runningindocker 4096 Jun 15 20:52 transform

I don’t know anything about using named volumes. I don’t see any difference between the command for that and for mounting a folder from the host so I can’t tell you anything. I prefer to keep my config on a folder on the host so I can source control it more easily.

I’ve never understood the reason for running Docker on something as constrained as an RPi so I’ve never looked into it.

It does work on my x64 VM with the command from the docs and the openhab/openhab:2.3.0-amd64-debian image

It also does work with the openhab/openhab:2.3.0-armhf-debian image so something must be broken with the alpine image

It’s a known issue that the alpine container no longer works on armhf:

1 Like