Probleme mit RPI_GPIO in Docker-Container

Begonnen von yreiser, 28 August 2021, 20:02:35

Vorheriges Thema - Nächstes Thema

yreiser

Ich versuche gerade, FHEM auf Docker umzuziehen.
Soweit klappt auch alles... bis auf das Steuern und Auslesen der GPIO Pins mittels RPI_GPIO Moduls. Seit Stunden suche ich nach einer Lösung.

Sobald ich einen RPI_GPIO Device anlege, kommt:
PERL WARNING: Can't exec "export": No such file or directory at ./FHEM/51_RPI_GPIO.pm line 647.
PERL WARNING: Use of uninitialized value $exp_result in pattern match (m//) at ./FHEM/51_RPI_GPIO.pm line 649.
PERL WARNING: Use of uninitialized value $exp_result in concatenation (.) or string at ./FHEM/51_RPI_GPIO.pm line 659.

Hier mein docker-compose yml file, in der ich schon verschiedene Ansätze (erfolglos) ausprobiert habe:
version: '3'

services:
    fhem:
        image: fhem/fhem:latest
        restart: always
        ports:
            - "8083:8083"
        container_name: fhem
        volumes:
            - ~/data/fhem:/opt/fhem/
            - /sys/class/gpio:/sys/class/gpio
        networks:
            - fhem-network
        devices:
            - "/dev/gpiomem:/dev/gpiomem"
            - "/dev/mem:/dev/mem"

        environment:
            FHEM_UID: 1000
            FHEM_GID: 1000
            TIMEOUT: 10
            RESTART: 1

Hat jemand eine Ahnung, was da schief läuft?




herrmannj

#1
Ich lehne mich mal weit aus dem Fenster und behaupte dass das im Container nicht geht. Wobei es durchaus sein kann dass jemand weiß wie es geht.

Otto123

#2
Kurz gegoogelt aber selbst keine Ahnung (aber interessantes Thema):
ZitatDas Modul RPI_GPIO für den Zugriff auf die GPIO Pins des Raspberry wird bereits mit FHEM mitgeliefert. Die Ansteuerung der GPIOs erfolgt über das Filesystem (sysFs). Daher werden in den meisten Anwendungsfällen keine weiteren Programme/Treiber benötigt.
ZitatUsing the sysfs filesystem on the host
The Pi's GPIO is represented within the host's file system underneath /sys/class/gpio. This can be accessed with user privileges via the virtual files in that file system. Use Docker volumes to expose this to your container:

$ docker run -v /sys:/sys -d whatever

Gpiomem ist also mMn der falsche Weg.

Berechtigungen gesetzt?
ZitatDer Benutzer ,,fhem" wird der Gruppe ,,gpio" hinzugefügt (funktioniert nur unter manchen Distributionen, z.B. Raspbian): sudo adduser fhem gpio

Wobei ich nicht genau weiß, was das drinnen und draußen in docker bedeutet :-[
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

yreiser

Nun funktioniert doch alles perfekt. Kein Problem, die GPIO's aus dem Container raus zu starten.
Wichtig ist, dass im host der user fhem der Gruppe gpio hinzugefügt wird (und danach ein Reboot erfolgt):

Das funktionierende Minimal-Docker-Compose-Script sieht jetzt bei mir so aus:


version: '3'

services:
    fhem:
        image: fhem/fhem:latest
        restart: always
        ports:
            - "8083:8083"
        container_name: fhem
        volumes:
            - ~/data/fhem:/opt/fhem/
            - /sys/class/gpio:/sys/class/gpio
            - /sys/devices/platform:/sys/devices/platform

        networks:
            - fhem-network
       
        environment:
            GPIO_GID: 997
            FHEM_UID: 1001 # oder id eines anderen users
            FHEM_GID: 1001 # oder id eines anderen users
            TIMEOUT: 10
            RESTART: 1
            TZ: Europe/Berlin

Otto123

#4
Schön zu wissen, dass es funktioniert - aber
Zitat von: yreiser am 29 August 2021, 02:31:40
Wichtig ist, dass im host der user fhem der Gruppe gpio hinzugefügt wird (und danach ein Reboot erfolgt):
Der Satz ist mir zu einfach :)
Im Normalfall gibt es auf dem Host keinen User fhem ;)
Du hast den Zugriff über die Umgebung geregelt
            GPIO_GID: 997
            FHEM_UID: 1001 # oder id eines anderen users
            FHEM_GID: 1001 # oder id eines anderen users

Du hast die Gruppe gpio vom host in den Container gemappt.
Du hast den User fhem im container (und die Group fhem) auf einen user mit der uid 1001 im Host gemappt.

Der user uid 1001 im Host ist offenbar Mitglied in der Gruppe gpio.

Ich bin da noch nicht sattelfest ('was das drinnen und draußen in docker bedeutet'), deswegen habe ich einfach mal versucht das aufzuschreiben. :)

Nachtrag:
Im Container ist der user fhem in der group gpio
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

herrmannj


Otto123

#6
Ich denke, dass einzig wesentliche an der obigen Lösung ist:
volumes:
  - /sys/class/gpio:/sys/class/gpio
environment:
  GPIO_GID=997

Alles andere dürfte nichts für den erfolgreichen Zugriff auf GPIO beitragen.

Bin mir aber noch nicht sicher, ob das wirklich die bevorzugte Vorgehensweise ist.  :D
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

yreiser

Lief bei mir erst, nachdem ich zusätzlich:
- /sys/devices/platform:/sys/devices/platform

eingefügt habe.

Und das zu finden hat viel Zeit gebraucht.

Otto123

#8
Interessant. 8)
Ich hatte meine Focus auf die Berechtigungen gelegt, da meine ich: das Einzige was man tun muss ist GPIO_GID=997 - der Rest an Berechtigungsmanipulation sollte überflüssig sein.

Bei dem Volume Mapping findet man viele Beispiele da wird dann gleich /sys:/sys gemappt. :-\
Offenbar könnte man auch noch "tiefer" gehen /sys/devices/platform/soc/3f200000.gpio aber da wird es dann schon sehr spezifisch.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

herrmannj

ich bin bisher intuitiv (falsch;)) immer davon ausgegangen dass das nicht geht . Ich finde das total spannend. Ob man aus dem container auch auf den i2c des host kommt?

Otto123

warum nicht? Wo doch hier: https://github.com/fhem/fhem-docker analog zu GPIO was von I2C_GID steht ;)

Allerdings find ich auf die Schnelle nur die Erwähnung im docker Thread das es eingebaut ist.  Kein praktisches Beispiel
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

herrmannj

spannend. Im docker compose scheinen aber auch die GPIOs nicht behandelt zu werden. Bräuchte man aber auch eine spezielle Raspi (oder so) Version des Files weil auf sonstigen Server dass ja keine rolle spielt

rudolfkoenig

ZitatOb man aus dem container auch auf den i2c des host kommt?
Der Container ist "nur" eine ausgefeilte chroot Umgebung. Da man diesen "Kerker" selektiv aufweichen kann (via mounts, Port-Weiterleitungen, etc), kann man alles ermoeglichen, irgendwann bleibt halt die versprochene Sicherheit (im Sinne das FHEM im Docker das Gastsystem nicht kaputtmachen kann)  auf der Strecke.

Otto123

#13
Jetzt kapern wir :) aber schweifen nicht vom Thema ab :)

spezielle Version GPIO/I2C -> Ich meine ich habe was von armhf Version gelesen ...

Ansonsten sind es ja im docker-compose nur die Abschnitte
devices:
volumes:
environment:
relevant - über die GPIO behandelt wird?

... und spätestens bei sowas /sys/devices/platform/soc/3f200000.gpio wird es Hardware/Host spezifisch. Bei sowas /sys:/sys wird es "unsicher" :) deswegen würde ich ja gerne immer "genau das empfehlen, was man braucht" und nicht "alles, damit es erstmal geht".
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

herrmannj

Das Sicherheitsversprechen würde ich nicht überschätzen. Im Kern gehts bei Docker (ursprünglich als Microservices) ja auch erst einmal darum das eine Anwendung (Teile von..) alle Abhängigkeiten mitbringt, kapselt und so eine in sich geschlossene, vorhersagbare Umgebung bereitsstellt.

Der Sicherheitseffekt ist nur sekundär und dünn. Beispielsweise kann ein Prozess im docker unter uid xyz laufen. Die uid wird von host nicht angezweifelt wenn dessen Prozesse aufgerufen werden. Selbst wenn die uid für den host dann root bedeutet.