mqtt-io icon indicating copy to clipboard operation
mqtt-io copied to clipboard

Docker Support

Open S-Przybylski opened this issue 5 years ago • 24 comments

Does somebody know, if this project was already ported into a docker container? Reason: my Smart Home concept completly rely on Docker (simplified lifecycle, easy to maintain).

I know that i have to connect the necessary hardware devices to the container ...

S-Przybylski avatar Mar 08 '19 15:03 S-Przybylski

Interesting idea! There's nothing to stop it from running in docker, but you'd have to work out how to pass the devices through, as you mention.

Nobody that I'm aware of has made a Dockerfile for that, but I can make one soon if you like.

flyte avatar Mar 08 '19 17:03 flyte

+1 need docker container plx

blademckain avatar May 02 '19 14:05 blademckain

@S-Przybylski @blademckain I've added a Dockerfile now, and published an auto-building image on Docker Hub. Please have a look at the bottom of the readme, which now explains a bit about how to run this project on Docker.

At the moment the hardware side is untested, since I don't have a Pi with Docker handy, so please report back here if it worked or not, and any other updates you think should be made.

Cheers

flyte avatar May 26 '19 12:05 flyte

Dear @flyte currently i have to organize an additional test environment because my actual hardware is in use by another project. I'will come back later to test ...

S-Przybylski avatar Jun 03 '19 20:06 S-Przybylski

Docker image doesnot work on Raspberry Pi zero. standard_init_linux.go:190: exec user process caused "exec format error"

hemantkamalakar avatar Jul 31 '19 15:07 hemantkamalakar

Dear @flyte today i tested your docker image. It seems that the image is prepared for Intel/AMD CPUs. It doesn't run on RASPI 3 ... Cold you please check to correct the target platform to ARMv7?

S-Przybylski avatar Oct 13 '19 15:10 S-Przybylski

I also would love to run this on an actual raspberry pi, please support armv6+ so we can run this 😄

RezzZ avatar Oct 30 '19 10:10 RezzZ

so grabbed the repo and changed the first line of the Dockerfile to

from arm32v7/python:3.6-stretch

one step further but I get the error

RuntimeError: No access to /dev/mem.  Try running as root!

I mapped the proper gpio port to docker: /dev/gpiomem so not sure why this docker is giving this error. Tried setting privileged mode but it doesn't help and is not really how I want to setup this container.

RezzZ avatar Oct 30 '19 13:10 RezzZ

@RezzZ did you use --device=/dev/mem:/dev/mem --device=/dev/gpiomem:/dev/gpiomem in your docker run command?

If that doesn't work, perhaps try starting from a raspbian image and installing Python etc.? https://hub.docker.com/r/raspbian/stretch

flyte avatar Oct 30 '19 16:10 flyte

It may also be an issue with permissions. Double check which user owns the /dev/mem device inside the container, and make sure that user exists and is the one the process is running as within the container. That, or run as root in the container, at least to test it with.

flyte avatar Oct 30 '19 16:10 flyte

@RezzZ did you use --device=/dev/mem:/dev/mem --device=/dev/gpiomem:/dev/gpiomem in your docker run command?

If that doesn't work, perhaps try starting from a raspbian image and installing Python etc.? https://hub.docker.com/r/raspbian/stretch

so far I've tried (in docker-compose):

      - /dev/gpiomem
      - /dev/mem

      - /dev/gpiomem:/dev/gpiomem
      - /dev/mem:/dev/mem

    privileged: true

the container keeps rebooting. I'll see if I can send a command in the few seconds the container is live to check user permissions to /dev/mem /dev/gpiomem

RezzZ avatar Oct 31 '19 12:10 RezzZ

It may also be an issue with permissions. Double check which user owns the /dev/mem device inside the container, and make sure that user exists and is the one the process is running as within the container. That, or run as root in the container, at least to test it with.

the user that has acecss to /dev/gpiomem is root:997. The user you create in the docker container (mqttgpio) doesn't seem to have access. I'll dive in a bit more to find out how to solve this

RezzZ avatar Oct 31 '19 12:10 RezzZ

Dear @RezzZ perhaps you could add a additional groups to the user (docker-compose.yaml):

    group_add: 
      - 998
      - 997

I tried to enable pcf8574 support for a node-red package to avoid maximum rights. Here are my results (docker-compose.yaml).

  nodered:
    container_name: nodered
    image: nodered/node-red:latest
#    privileged: true
    user: "1000:1000"
    group_add: 
      - 998
      - 997
    ports:
      - 1880:1880
    volumes:
      - /<your persistant storage>/nodered:/data
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /sys/class/gpio:/sys/class/gpio:rw
      - /sys/class/gpio/export:/sys/class/gpio/export:rw
      - /sys/devices/platform/soc/3f200000.gpio/gpiochip0:/sys/devices/platform/soc/3f200000.gpio/gpiochip0:rw
    devices:
      - /dev/i2c-1:/dev/i2c-1

S-Przybylski avatar Oct 31 '19 13:10 S-Przybylski

@S-Przybylski group_add is no longer supported in v3 of docker-compose. I'm looking into alternatives atm for newer compose files (eg. changing the Dockerfile and assigning groups already inside the image)

RezzZ avatar Nov 01 '19 09:11 RezzZ

new Dockerfile that works on rpi3b+. Total of three changes: line 1: added arm32v7 to specify a raspberry (2+) compatible python image line 8: add usergroup gpio with gid 997 line 9: assign uid 1000 and gid 997 to user mqttgpio (uid 1000 is not really needed though)

from arm32v7/python:3.6-stretch

ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

RUN pip install --no-cache-dir pipenv

RUN groupadd -g 997 gpio
RUN useradd -m -s /bin/bash -u 1000 -g 997 mqttgpio

USER mqttgpio
WORKDIR /home/mqttgpio

COPY Pipfile* ./
RUN pipenv install --three --deploy

COPY pi_mqtt_gpio pi_mqtt_gpio

CMD [ "pipenv", "run", "python", "-m", "pi_mqtt_gpio.server", "/config.yml" ]

next todo: reduce filesize as this container is massive compared to what it should do for me, which is (only) publish state changes on gpio pins. Trying buster slim next.

RezzZ avatar Nov 01 '19 09:11 RezzZ

hmm now that the container is running stable I tried setting up a simple input sensor (door sensor) but my knowledge of setting this up via python is a bit limited. I had this sensor hooked up in HomeAssistant (which has default pull mode = UP) using this simple config:

binary_sensor:
  - platform: rpi_gpio
      35: Door meter closet

I tried converting this logic to pgiomqtt:

digital_inputs:
  - name: door_metercloset
    module: raspberrypi
    pin: 35
    on_payload: "ON"
    off_payload: "OFF"
    pullup: yes
    pulldown: no
    retain: yes

but this doesn't give me any state changes. As said my knowledge over setting this up in python is limited, so is my pull-up/pull-down resistor knowledge. Any chance someone can point me to a website where this is explained?

RezzZ avatar Nov 01 '19 11:11 RezzZ

and we keep learning 😄 the pin nr required in the config.yml is not the actual pin nr of your raspberry pi but the GPIOnr. pin nr 35=GPIO19, so the config want pin: 19. image source

RezzZ avatar Nov 01 '19 11:11 RezzZ

update on useing the python slim image. first try ended with a gcc not found error. After adding the installation of gcc it works. Filesize reduces from 786.9 MB to 226.4 MB. Next I'll try alpine

Dockerfile:

from arm32v7/python:3.6-slim-stretch

ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

RUN apt-get update && apt-get install -y gcc
RUN pip install --no-cache-dir pipenv

RUN groupadd -g 997 gpio
RUN useradd -m -s /bin/bash -u 1000 -g 997 mqttgpio

USER mqttgpio
WORKDIR /home/mqttgpio

COPY Pipfile* ./
RUN pipenv install --three --deploy

COPY pi_mqtt_gpio pi_mqtt_gpio

CMD [ "pipenv", "run", "python", "-m", "pi_mqtt_gpio.server", "/config.yml" ]

RezzZ avatar Nov 01 '19 23:11 RezzZ

I made some suggestion in #112 including a proposal for a Dockerfile with alpine base. I would love your feedback.

ebekebe avatar May 31 '20 15:05 ebekebe

Docker image doesnot work on Raspberry Pi zero. standard_init_linux.go:190: exec user process caused "exec format error"

its not built for armv6, I have tried to locally build Dockerfile but there is almost no support for armv6 for base image to rely on for building on RPI zero, gave up, switched to RPI 3b

IlmLV avatar Jun 17 '20 19:06 IlmLV

Hi,

I'm a newbie in this, so sorry for the newbie question.

I'm trying to run this on docker, and I'm getting this error

RuntimeError: No access to /dev/mem. Try running as root!

I understand that what @RezzZ mentioned in post https://github.com/flyte/mqtt-io/issues/55#issuecomment-548981952 is already incorporated in the latest Dockerfile, am I right?

If not, what I'd have to do is to clone the repository to my git, then make the changes as the comments suggested, then pull from my repository, is that right?

Thank you in advanced

luvxinh avatar Apr 03 '22 10:04 luvxinh

Same sorcery needed as in https://github.com/naztronaut/dancyPi-audio-reactive-led/issues/35#issuecomment-867670891

docker run --network host --privileged --user root -v ${PWD}/mqtt_gpio_config.yaml:/config.yml flyte/mqtt-io bash -c "setcap 'cap_sys_rawio+eip' \$(readlink -f venv/bin/python) && venv/bin/python -m mqtt_io /config.yml"

So python needs to be granted the capability to access raw IO for the raspberry gpio to work. Maybe @flyte could consider to add this into the Dockerfile in case there is no better workaround.

lassi-niemisto avatar Sep 17 '22 14:09 lassi-niemisto

Same sorcery needed as in naztronaut/dancyPi-audio-reactive-led#35 (comment)

docker run --network host --privileged --user root -v ${PWD}/mqtt_gpio_config.yaml:/config.yml flyte/mqtt-io bash -c "setcap 'cap_sys_rawio+eip' \$(readlink -f venv/bin/python) && venv/bin/python -m mqtt_io /config.yml"

So python needs to be granted the capability to access raw IO for the raspberry gpio to work. Maybe @flyte could consider to add this into the Dockerfile in case there is no better workaround.

Thanks a lot for this, here is a docker-compose file for portainer using the fixes:

version: '3'
services:
  mqtt-io:
    tty: true
    privileged: true
    user: root
    image: flyte/mqtt-io
    ports:
     - "443:443"
     - "1883:1883"
     - "8883:8883"
     - "14567:14567"
    volumes:
      - type: bind
        source: /portainer/Files/AppData/Config/mqtt-io/config.yml
        target: /config.yml
        read_only: true
      - /dev/i2c-0:/dev/i2c-0
      - /dev/mem:/dev/mem
      - /dev/gpiomem:/dev/gpiomem
    devices:
      - /dev/i2c-0
      - /dev/mem
      - /dev/gpiomem
    command: >
      bash -c "setcap 'cap_sys_rawio+eip' $(readlink -f venv/bin/python) && venv/bin/python -m mqtt_io /config.yml"
    network_mode: host

Bluscream avatar Jan 13 '24 21:01 Bluscream

Same sorcery needed as in naztronaut/dancyPi-audio-reactive-led#35 (comment)

docker run --network host --privileged --user root -v ${PWD}/mqtt_gpio_config.yaml:/config.yml flyte/mqtt-io bash -c "setcap 'cap_sys_rawio+eip' \$(readlink -f venv/bin/python) && venv/bin/python -m mqtt_io /config.yml"

So python needs to be granted the capability to access raw IO for the raspberry gpio to work. Maybe @flyte could consider to add this into the Dockerfile in case there is no better workaround.

Thanks a lot for this, here is a docker-compose file for portainer using the fixes:

version: '3'
services:
  mqtt-io:
    tty: true
    privileged: true
    user: root
    image: flyte/mqtt-io
    ports:
     - "443:443"
     - "1883:1883"
     - "8883:8883"
     - "14567:14567"
    volumes:
      - type: bind
        source: /portainer/Files/AppData/Config/mqtt-io/config.yml
        target: /config.yml
        read_only: true
      - /dev/i2c-0:/dev/i2c-0
      - /dev/mem:/dev/mem
      - /dev/gpiomem:/dev/gpiomem
    devices:
      - /dev/i2c-0
      - /dev/mem
      - /dev/gpiomem
    command: >
      bash -c "setcap 'cap_sys_rawio+eip' $(readlink -f venv/bin/python) && venv/bin/python -m mqtt_io /config.yml"
    network_mode: host

With privileged set to true you don't need to define devices, this option gives the container access to all devices on the host. This allows the container nearly all the same access as processes running on the host.

RezzZ avatar Jan 14 '24 08:01 RezzZ