Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
12.17k stars 1.68k forks source link

Cannot startup Zigbee2Mqtt in Docker. No problems as a service. #5910

Closed kylehild closed 3 years ago

kylehild commented 3 years ago

What happened

I can start Zigbee2Mqtt as a service on my host just fine. When I try to run it as a docker container, I am getting this dreaded Failed to connect to the adapter (Error: SRSP - SYS - ping after 6000ms) issue that seems to plague many users.

What did you expect to happen

Zigbee2Mqtt should start using docker.

How to reproduce it (minimal and precise)

I am currently using this docker-compose setup after trying to add as much logging as possible and doing as much debugging as possible. You can see I am overwriting the entrypoint for the container in order to get onto the container before it fails.

  zigbee2mqtt:
    container_name: zigbee2mqtt
    image: koenkk/zigbee2mqtt
    volumes:
      - ${USERDIR}/Zigbee2Mqtt:/app/data
      - /run/udev:/run/udev:ro
    environment:
      - TZ=${TZ}
      - DEBUG=zigbee-herdsman*
    devices:
      - /dev/ttyACM0:/dev/ttyACM0
    restart: always
    network_mode: host
    privileged: true
    entrypoint: /bin/sh
    stdin_open: true

Here is my output when accessing the container and running npm start https://pastebin.com/N33kFzfA I've been stuck on this for a few days so any help would be greatly appreciated!

Debug info

Zigbee2MQTT version: 1.17.0 Adapter hardware: CC2531 Adapter firmware version: CC2531_DEFAULT_20190608

m0wlheld commented 3 years ago

I think this is related to permissions on the serial device. Can you try an alternative path to the serial adapter, like /dev/serial/by-id/... or /dev/ttyUSB0?

Don‘t forget to pass that device path into Docker as well.

kylehild commented 3 years ago

Yeah, I suspect some kind of docker permission issue as well. Weirdly, when I go to the docker image, there is no /dev/serial directory that I could use to get the correct USB device. I have also tried mounting the device /dev/CC2531:/dev/CC2531 and volume /etc/udev/rules.d:/etc/udev/rules.d on docker as well but /dev/CC2531 doesn't show up when I ls -la /dev from docker either.

m0wlheld commented 3 years ago

That's because they are on the host and need to be "mounted" into the container. Since you are using docker-compose, you need to add the proper device's path on the host (/dev/serial/by-id/... is preferred) to your devices: section. And of course, you must reflect the device-path inside the container in your configuration.yaml

You can try beforehand running a temporary container instance:

docker run --rm -it --device /dev/serial/by-id/...:/dev/ttyACM0 koenkk/zigbee2mqtt

If that works, kill the container with Ctrl-c and copy the --device mapping to your docker-compose.yml

    devices:
      - /dev/serial/by-id/...:/dev/ttyACM0
kylehild commented 3 years ago

Okay, that got me on the right track. For whatever reason it was working using docker commands but not using docker-compose. Removing privileged: true from docker-compose fixed the issue for me. Thanks for your help @m0wlheld!

D43m0n commented 3 years ago

I've been running into this dreaded Error: Failed to connect to the adapter (Error: SRSP - SYS - ping after 6000ms) error to as a newbie. I've re-flashed my CC2652R stick and checked a lot of things and it turns out that removing privileged: true from docker-compose was indeed all that needed to be done.

One could wonder why privileged: true is required as it seems to break zigbee2mqtt from even starting up. I can't set PUID or GUID on the default container image so does that mean it's running privileged by default in that case?

gonzo09 commented 2 years ago

That's because they are on the host and need to be "mounted" into the container. Since you are using docker-compose, you need to add the proper device's path on the host (/dev/serial/by-id/... is preferred) to your devices: section. And of course, you must reflect the device-path inside the container in your configuration.yaml

You can try beforehand running a temporary container instance:

docker run --rm -it --device /dev/serial/by-id/...:/dev/ttyACM0 koenkk/zigbee2mqtt

If that works, kill the container with Ctrl-c and copy the --device mapping to your docker-compose.yml

    devices:
      - /dev/serial/by-id/...:/dev/ttyACM0

Hello @m0wlheld In my case I use the serial/by-id path in the docker-compose file as following:

zigbee2mqtt:
    container_name: zigbee2mqtt
    restart: unless-stopped
    image: koenkk/zigbee2mqtt
    volumes:
      - ./zigbee2mqtt/zigbee2mqtt-data:/app/data
      - /run/udev:/run/udev:ro
    ports:
      - 8080:8080
    environment:
      - TZ=Europe/Paris
    devices:
      - "/dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2486910-if00:/dev/ttyACM1"

And in the configuration.yaml:

serial:
  port: /dev/ttyACM1

But what I don't understand is that if I change the /dev/ttyACM1 to/dev/ttyACM0 (as it sometimes automatically happens on reboot) on both files, zigbee2mqtt displays the same error as @kylehild. Isn't the role of the docker devicesmapping to be independant from the real serial port ? What if I want to use /dev/foo for example ?

m0wlheld commented 2 years ago

Did you change to ttyACM0 in your compose file and Z2M‘s configuration file?

gonzo09 commented 2 years ago

Yes, I changed it on both file.