Check config via SSH inside Docker container?

Hi,

Is it possible to check config via SSH in an Docker container?
I have tried with this command:

docker exec -it Homeassistant hass --script check_config

Where “Homeassistant” is my docker container name.
This is the result:
oci runtime error: exec failed: container_linux.go:265: starting container proce ss caused "exec: \"hass\": executable file not found in $PATH"

When checking the contents of the container, I can see that there is a folder called “homeassistant” in the root of the container, and inside this folder is the following:

__init__.py   components  exceptions.py    package_constraints.txt  util
__main__.py   config.py   helpers          remote.py
__pycache__   const.py    loader.py        scripts
bootstrap.py  core.py     monkey_patch.py  setup.py

And I can find the check_config.py inside the “scripts”-folder.

So how do I run this via SSH?

Is there any reason you need to run it inside the container? If you’re able to exec into the container then you obviously have access to the host - this means you can just bring up another container with the config mapped in to check it:

docker run -it --rm -v /opt/docker/home-assistant/config:/config -v /etc/localtime:/etc/localtime:ro homeassistant/raspberrypi3-homeassistant hass -c /config --script check_config

Passing --rm will cause the container to be removed once the check has run, and for extra security you can map your config volume as read-only to ensure the config check doesn’t write anything to it (it does write to the log file):

-v /opt/docker/home-assistant/config:/config:ro

Hmm… I don’t really understand this. I thought I had to run it inside the container, as that is the “virtual machine” that runs Home Assistant. But if I don’t have to do it inside the container itself, can’t I just run it on my host machine instead?

The config folder is mapped to /home/docker/.config/homeassistant
But this folder does not include the check_config?

Do I really need to create a new container each time I run check_config?

EDIT: And when I run hass --script check_config inside the container it doesn’t work?

Hmm… I don’t really understand this. I thought I had to run it inside the container, as that is the “virtual machine” that runs Home Assistant. But if I don’t have to do it inside the container itself, can’t I just run it on my host machine instead?

The only reason you need to run it in the homeassistant container is to use the scripts which are in the container to check the config. Containers shouldn’t be thought of like virtual machines, they’re more lightweight than that - you can fire up another one and it just runs long enough to check the config and then it exits. If you pass the --rm flag then it will also delete the config checking container once it has exited too - you don’t need the container to exist after it as finished checking. I’ll show you what mine does:

$ docker run -it --rm -v /opt/docker/home-assistant/config:/config -v /etc/localtime:/etc/localtime:ro homeassistant/raspberrypi3-homeassistant hass -c /config --script check_config
starting version 3.2.2
Testing configuration at /config
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setting up mqtt
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setting up http
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setting up recorder
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setup of domain mqtt took 0.0 seconds.
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setup of domain http took 0.0 seconds.
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setup of domain recorder took 0.0 seconds.
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setting up api
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setting up websocket_api
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setting up history
2017-11-28 11:56:15 INFO (MainThread) [homeassistant.setup] Setup of domain api took 0.0 seconds.
-- snip --

So it’ll run a new homeassistant container, check your config, print the results to your terminal and then exit.

The config folder is mapped to /home/docker/.config/homeassistant
But this folder does not include the check_config?

No, that’s correct - it’ll be part of the Python package which makes up home assistant. When you start a docker container, everything after the image name is the command which is run inside the container, so you’re basically just running hass -c /config --script check_config - the rest of the docker run command is just setting the container up for this to work.

Do I really need to create a new container each time I run check_config?

Don’t think of it as running a new container, just think of it like you’re running a process on the host machine itself.

EDIT: And when I run hass --script check_config inside the container it doesn’t work?

I would expect that that’s something to do with the environment variables inside container - when you exec in the path to the hass process might not be in your $PATH.

Why don’t you adjust the command in my initial reply to use the right image name and config path for your setup and then try it?

1 Like

I understand what you mean with running it in a temporary container. But what I don’t understand is why I am not able to run hass at all, why the executable file is not found in PATH?

Why isn’t it working when I run it like this?

docker exec -it Homeassistant hass -c /config --script check_config
This is the result:
oci runtime error: exec failed: container_linux.go:265: starting container process caused "exec: \"hass\": executable file not found in $PATH"

Before I start working with a new container, I want to check if I even can run this at all? It fails every time.

OK, what happens if you run which hass inside your running container?

$ docker exec -it hass which hass
/usr/bin/hass

Also, which container are you using? Can you link to it on the Docker Hub?

I assume you’re running the homeassistant/home-assistant image. If that’s the case, it does not have an executable named hass. Try using the homeassistant/amd64-homeassistant image instead.

Yes, I use https://hub.docker.com/r/homeassistant/home-assistant/

Why is there two different docker images?
What is the difference between them?

I’m not sure if I want to start over with the setup again. Is there anything I’m missing using the homeassistant/home-assistant image?

From what I can see that seems like the official one?

As @analbeard said, just launch another container to test your config. Just use the homeassistant/amd64-homeassistant image instead.

docker run -it --rm -v /opt/docker/home-assistant/config:/config -v /etc/localtime:/etc/localtime:ro homeassistant/amd64-homeassistant hass -c /config --script check_config

The image named homeassistant/amd64-homeassistant is used by hassio and homeassistant/home-assistant is the standard non-hassio image. As for the other differences, I’m not sure because I haven’t researched it. Personally, I use hassio running on Ubuntu, so I don’t have much experience with the homeassistant/home-assistant image.

Docker is not processor independent. There has to be a different image for every type of processor (amd64, atom etc). Each one should have the same structure though.

So I could keep the docker image I have installed right now, and install another docker image temporarly just to check the config, and this time use the amd64 variant?

I researched this a little bit, and from what I understand it is no point to run Hassio in Docker, as Hassio itself is pretty much a docker container with everything built in for easy installation and updating on Raspberry Pi and such.

But do you mean there is a special version for every processor type? I just thought there were different version for ARM and AMD64? I have an Intel Xeon processor in my server running Debian.

Why do you run the Hassio image by the way?

I use HA on a Raspberry Pi, but it does appear that the one you’re talking about is the latest version of the official image.

I’ve just pulled the image you’re using on my laptop and I can see your problem. There’s no pythonpath in the env variables so when you exec into the container you won’t have hass in your path. I got it to work with this command:

python -m homeassistant --config /config

So taking that, you could spawn your test container with this command:

docker run -it --rm -v /home/docker/.config/homeassistant:/config -v /etc/localtime:/etc/localtime:ro homeassistant/home-assistant python -m homeassistant --config /config --script check_config
1 Like

Yes

Hassio isn’t just for the Raspberry Pi. You can run it on top of a generic Linux install running on x86, amd64, or armhf. The benefits you get from hassio is that you can take advantage of all of the hassio addons without needing to worry about managing those containers. Since it would be running on top of a generic Linux OS, you can also run your own containers in Docker just like you’re doing now. You can think if it like the getting the best of both Docker and hassio options…

Yes

I’m running hassio on Ubuntu. See hassio-build/install at master · home-assistant/hassio-build · GitHub and Installation - Home Assistant for more details about running hassio on Linux (instead of ResinOS).

Fantastic work! :smiley: it works flawlessly! Is it possible to somehow write this to a log-file which is stored on the server? And that it overwrites this logfile everytime?

I tried the container command you wrote! Ran like a dream!
Will there be any leftover containers after this has ran?

do a bind mount to a directory on your server, and output the results to that log file with >?

Could you not just have a copy of the hass binary accessible to your ssh session?

In theory you should be able to do something like this:

docker run -it --rm -v /home/docker/.config/homeassistant:/config -v /home/docker/.config/halog:/tmp/halog -v /etc/localtime:/etc/localtime:ro homeassistant/home-assistant python -m homeassistant --config /config --log-file /tmp/halog/check_config.log --script check_config

Which will cause the log from the config check to end up in /home/docker/.config/halog on your docker host, however the --log-file arg fails for me with hass: error: unrecognized arguments: --log-file /config/testy.log, even though it exists in __main__.py for me. Not sure why that’s happening - it may work for you though (this flag was added by this PR: https://github.com/home-assistant/home-assistant/pull/9422).

And no, as long as you give the check container the --rm flag then Docker will clean up after the container has exited.

This seems to work for me

docker exec -it home-assistant python -m homeassistant --config /config --script check_config

3 Likes

Hi

I try to ssh to container:

When I run command:
docker exec -i -t 4fd233393ffd /bin/bash
Error: No such container: 4fd233393ffd

root@hassio:/# docker images
REPOSITORY                                 TAG                 IMAGE ID            
27e642c6/armhf-addon-nodered               0.1.12              4fd233393ffd

How to ssh to addon container?

how could I get a proper non-zero exit code for the config check, if there’s an error in the config ?

# docker run --rm -v /opt/docker/home_assistant:/config homeassistant/home-assistant python -m homeassistant --config /config --script check_config
Testing configuration at /config
ERROR:homeassistant.util.yaml:YAML file /config/customize.yaml contains duplicate key "switch.influxdb". Check lines 102 and 104.
# echo $?
0


# docker run --rm -v /opt/docker/home_assistant:/config homeassistant/home-assistant bash -c "python -m homeassistant --config /config --script check_config ; echo $?"
Testing configuration at /config
ERROR:homeassistant.util.yaml:YAML file /config/customize.yaml contains duplicate key "switch.influxdb". Check lines 102 and 104.
0

I didn’t expect check_config to return 0 if there’s a failure, is it normal ?

@flamingm0e @analbeard @balk77