iot: "Error 13 initializing the Gpio driver" with .NET 8 in rootless container

Describe the bug

After upgrading my app to .NET 8 and switching to rootless containers (corresponding commit), the following exception occurs when trying to access a Raspi’s GPIO pin :

Unhandled exception. System.IO.IOException: Error 13 initializing the Gpio driver.
   at System.Device.Gpio.Drivers.RaspberryPi3LinuxDriver.Initialize()
   at System.Device.Gpio.Drivers.RaspberryPi3LinuxDriver.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.Drivers.RaspberryPi3Driver.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPinCore(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPin(Int32 pinNumber, PinMode mode)
   at RaspiFanController.Logic.RaspiFanController..ctor(ILogger`1 logger, IOptionsMonitor`1 settings) in /home/runner/work/RaspiFanController/RaspiFanController/RaspiFanController/Logic/RaspiFanController.cs:line 16

Steps to reproduce

  1. Clone/fork my repo
  2. Call dotnet publish RaspiFanController/RaspiFanController.csproj --os linux --arch arm64 /t:PublishContainer
  3. Start a Docker container on a Raspberry Pi 4 with the following docker-compose.yml:
version: '3'
services:
    app:
        environment:
            - LD_LIBRARY_PATH=/opt/vc/lib
            - AppSettings__UpperTemperatureThreshold=70
            - AppSettings__LowerTemperatureThreshold=55
        restart: unless-stopped
        image: mu88/raspifancontroller:latest
        ports:
            - 127.0.0.1:5000:8080
        volumes:
            - /lib:/lib
            - /usr/bin/vcgencmd:/usr/bin/vcgencmd
        devices:
            - "/dev/vchiq"
            - "/dev/gpiomem"

Expected behavior

The GPIO pin can be accessed.

Actual behavior

The following exception occurs:

Unhandled exception. System.IO.IOException: Error 13 initializing the Gpio driver.
   at System.Device.Gpio.Drivers.RaspberryPi3LinuxDriver.Initialize()
   at System.Device.Gpio.Drivers.RaspberryPi3LinuxDriver.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.Drivers.RaspberryPi3Driver.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPinCore(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPin(Int32 pinNumber, PinMode mode)
   at RaspiFanController.Logic.RaspiFanController..ctor(ILogger`1 logger, IOptionsMonitor`1 settings) in /home/runner/work/RaspiFanController/RaspiFanController/RaspiFanController/Logic/RaspiFanController.cs:line 16

Versions used

  • dotnet --info: the project was built using a GitHub Action using .NET 8 and the SDK Container Building Tools
  • dotnet --info: the app is running inside a Docker container using .NET 8
  • Version of System.Device.Gpio package: 3.0.0
  • Version of Iot.Device.Bindings package: 3.0.0

CC: @baronfel (maybe interesting for you as well)

About this issue

  • Original URL
  • State: open
  • Created 7 months ago
  • Comments: 20 (10 by maintainers)

Commits related to this issue

Most upvoted comments

I would recommend to read couple of articles about this. See for example: https://medium.com/@nielssj/docker-volumes-and-file-system-permissions-772c1aee23ca. I’m quite sure adjusting the permissions should solve your problem! Nothing is urgent for the answer!

@pgrawehr when using the following docker-compose.yml, the exception Unhandled exception. System.IO.IOException: Error 13 initializing the Gpio driver. is back:

version: '3'
services:
  raspifancontroller:
    container_name: raspifancontroller
    user: app
    environment:
      - LD_LIBRARY_PATH=/opt/vc/lib
      - AppSettings__UpperTemperatureThreshold=70
      - AppSettings__LowerTemperatureThreshold=55
    restart: unless-stopped
    image: mu88/raspifancontroller:latest
    ports:
      - 127.0.0.1:5000:8080
    volumes:
      - /lib:/lib
      - /usr/bin/vcgencmd:/usr/bin/vcgencmd
      - /dev/gpiomem:/dev/gpiomem
    devices:
      - /dev/vchiq

@mu88 I’m not a container expert, but can you try moving the “/dev/gpiomem” to the “volumes” section?

Sure - the issue is https://github.com/dotnet/sdk-container-builds/issues/520.

As for what a root-less solution for gpio might look like, I don’t have a ton of experience with this specific problem. It’s The best I could find was this Stack Overflow answer that goes over some of the options - including running the container in privileged mode, mounting a device, or mounting a file system. It look like you’ve done the device mount, but that didn’t work, and you say that overriding the privilege setting didn’t work as well.

One thing to try might be using docker directly instead of docker compose just to rule out any problems in the compose layer that may not exist in the purely docker side.