Search code examples
dockerraspberry-pigpiogpiozero

Controlling GPIO from a Docker container in Raspberry Pi 5


I'm trying to use gpiozero to control GPIO in a container on Raspberry Pi 5. My simple LED blink application is

from gpiozero import LED
from time import sleep

led = LED(17)

while True:
    led.on()
    sleep(1)
    led.off()
    sleep(1)

While it works fine on the host, I can't get it to work from a Docker container. When I create the container with:

docker run  --privileged --device /dev/gpiochip4 -v /dev:/dev -v /sys:/sys blinker:latest

I get the error Unable to load any default pin factory!.

Here is the whole error trace:

/usr/local/lib/python3.11/site-packages/gpiozero/devices.py:300: PinFactoryFallback: Falling back from lgpio: module 'lgpio' has no attribute 'SET_BIAS_DISABLE'
  warnings.warn(
/usr/local/lib/python3.11/site-packages/gpiozero/devices.py:300: PinFactoryFallback: Falling back from rpigpio: No module named 'RPi'
  warnings.warn(
/usr/local/lib/python3.11/site-packages/gpiozero/devices.py:300: PinFactoryFallback: Falling back from pigpio: failed to connect to localhost:8888
  warnings.warn(
/usr/local/lib/python3.11/site-packages/gpiozero/devices.py:300: PinFactoryFallback: Falling back from native: unable to determine gpio base
  warnings.warn(
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Can't connect to pigpio at localhost(8888)

Did you start the pigpio daemon? E.g. sudo pigpiod

Did you specify the correct Pi host/port in the environment
variables PIGPIO_ADDR/PIGPIO_PORT?
E.g. export PIGPIO_ADDR=soft, export PIGPIO_PORT=8888

Did you specify the correct Pi host/port in the
pigpio.pi() function? E.g. pigpio.pi('soft', 8888)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Traceback (most recent call last):
  File "//blink.py", line 5, in <module>
    led = LED(17)
          ^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/gpiozero/devices.py", line 108, in __call__
    self = super().__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/gpiozero/output_devices.py", line 192, in __init__
    super().__init__(pin, active_high=active_high,
  File "/usr/local/lib/python3.11/site-packages/gpiozero/output_devices.py", line 74, in __init__
    super().__init__(pin, pin_factory=pin_factory)
  File "/usr/local/lib/python3.11/site-packages/gpiozero/mixins.py", line 75, in __init__
    super().__init__(*args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/gpiozero/devices.py", line 544, in __init__
    super().__init__(pin_factory=pin_factory)
  File "/usr/local/lib/python3.11/site-packages/gpiozero/devices.py", line 245, in __init__
    Device.ensure_pin_factory()
  File "/usr/local/lib/python3.11/site-packages/gpiozero/devices.py", line 270, in ensure_pin_factory
    Device.pin_factory = Device._default_pin_factory()
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/gpiozero/devices.py", line 302, in _default_pin_factory
    raise BadPinFactory('Unable to load any default pin factory!')
gpiozero.exc.BadPinFactory: Unable to load any default pin factory!

To create the image I used the following Dockerfile:

FROM python:3.11
COPY blink.py ./
RUN pip install lgpio pigpio gpio gpiozero
CMD ["python", "blink.py"]

In addition, I tried to expose port 8888, and I tried to expose differnt volumes under /dev folder. I validated daemon was running using sudo pigpiod and sudo systemctl enable pigpiod.


Solution

  • I found a workaround on GitHub in the repository PY_LGPI. You can update your Dockerfile as follows:

    FROM python:3.11
    
    COPY blink.py ./
    
    RUN pip install lgpio pigpio gpio gpiozero
    
    RUN wget https://github.com/Gadgetoid/PY_LGPIO/releases/download/0.2.2.0/lgpio-0.2.2.0.tar.gz
    RUN pip install lgpio-0.2.2.0.tar.gz
    
    CMD ["python", "blink.py"]
    

    Then, you can run the Docker container with the following command:

    docker run --privileged blinker:latest
    

    This should resolve the issue you were facing.