-
Notifications
You must be signed in to change notification settings - Fork 585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Error 13 initializing the Gpio driver" with .NET 8 in rootless container #2169
Comments
what if you add |
wow, that was a fast response! Adding |
For this you may need to have our tooling change the container user to root. The normal way to do this would be <ItemGroup>
<ContainerEnvironmentVariable Include="APP_UID" Value="root" />
</ItemGroup> |
Thx, I will try! Some additional questions:
|
Sure - the issue is dotnet/sdk-container-builds#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 |
Thank you for your help anyway! Let's see whether the GPIO experts know some additional details :) |
[Triage] @mu88 the pattern you can use is to mount and bind the folder from the host (so in our case /dev/gpiomem). See the example here: https://github.com/dotnet/iot/tree/main/samples/led-blink#running-in-containers See also more on the Docker docs: https://docs.docker.com/storage/volumes/ |
@Ellerbach can you please elaborate on the difference between your mentioned approach and the one I'm already using in my version: '3'
services:
app:
devices:
- "/dev/gpiomem" |
@mu88 I'm not a container expert, but can you try moving the "/dev/gpiomem" to the "volumes" section? |
@pgrawehr when using the following 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 |
Do you have further ideas? Just let me know if I can provide you more information :) |
Can you try without container? Does that work? |
Using this release (self-contained .NET 8 app for |
@mu88 I've never used docker on the RPI, but others have successfully done it. I'm not sure what exactly the problem is, but since the default Just create the GpioController with a call to: var controller = new GpioController(PinNumberingScheme.Logical, new SysFsDriver()); or var controller = new GpioController(PinNumberingScheme.Logical, new LibGpiodDriver()); Side note: We also have a binding for reading out the CPU temperature, so you don't need to make that ugly call to |
@pgrawehr thx for pointing me to the way more elegant way of resolving the CPU temperature 😵💪🏻🤩 Regarding Docker: running the app within a container is no problem at all. The problem only arises when switching from using root to a rootless container. It even works with the latest chiseled images, as long as I use the root user. |
Stupid question: did you gave the privileges for docker to access /dev/gpiomem ? You still have to make sure that the docker process have the proper rights on it. |
Stupid question back 😄: isn't the Docker process the same, no matter which user is used inside the container ( |
It may not have. Give access to the gpiomem so it can make things properly with low privilege. With high priviledges, the story is different! |
Learning never stops, I will try this 💪🏻 could you please give me a little guidance on how I can give the Docker user the necessary permissions? Thx a lot! Please bear with me that my feedback will take 1 month or so because I'm currently not at home. |
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! |
Okay, I played a bit with the permissions and can give you an update: for testing purposes, I permitted reading and writing to all users by executing However, simply allowing everybody to read/write So is the recommended approach to grant all others read and write permissions? Or create the CC @richlander (maybe interesting for you as well) |
First, happy, that it was about permissions ;-) There are multiple options to solve the problem. In short, it's about mapping the users from in to outside the container. This gives a good idea how to do it (well, I think): https://serverfault.com/questions/1075488/podman-rootless-container-permissions-for-container-user and most likely this one: https://stackoverflow.com/questions/39397548/how-to-give-non-root-user-in-docker-container-access-to-a-volume-mounted-on-the |
I think I'm getting closer, but still not there 🤪 Let me summarize the options according to my current understanding:
Options 1 and 2 seem too permissive to me, so I decided to go with option 3:
However, when starting my container with the newly created user, it still fails with the same error. So I checked the following things on the host: myUser@myRaspi:~ $ grep gpio /etc/group
gpio:x:997:myUser,app_raspi
myUser@myRaspi:~ $ grep app_raspi /etc/passwd
app_raspi:x:64200:64200:,,,:/home/app_raspi:/bin/bash
myUser@myRaspi:~ $ sudo -u \#64200 test -r /dev/gpiomem; echo "$?"
0
myUser@myRaspi:~ $ sudo -u \#64200 test -w /dev/gpiomem; echo "$?"
0
myUser@myRaspi:~ $ ls -lh /dev/gpiomem
crw-rw---- 1 root gpio 245, 0 Jan 6 12:00 /dev/gpiomem So I started the container with bash as entrypoint: I have no name!@9218798747ed:/app$ whoami
whoami: cannot find name for user ID 64200
I have no name!@9218798747ed:/app$ id
uid=64200 gid=0(root) groups=0(root)
I have no name!@9218798747ed:/app$ test -r /dev/gpiomem; echo "$?"
1
I have no name!@9218798747ed:/app$ test -w /dev/gpiomem; echo "$?"
1
I have no name!@9218798747ed:/app$ test -r RaspiFanController.dll; echo "$?"
0
I have no name!@9218798747ed:/app$ test -x RaspiFanController.dll; echo "$?"
0
I have no name!@9218798747ed:/app$ ls -lh /dev/gpiomem
crw-rw---- 1 root 997 245, 0 Jan 6 11:00 /dev/gpiomem So from the mentioned, very helpful blog posts I would have assumed that it should now work as |
I also filed this discussion in a Docker forum |
That is a character device file, not a folder actually. The @mu88 Reading the whole issue (and also the topic on the Docker forum), it seems the porblem is the lack of group membership in the container. Setting group membership on the host won't help, neither creating a user on the host. The user can be set by using the |
I finally have a working solution: as already mentioned by @rimelek , I had to specify the group ID What did not work with this approach was reading the Raspi's current temperature via This is my final version: '3'
services:
raspifancontroller:
container_name: raspifancontroller
user: "64198:997" # group 997 is necessary to access the GPIO pins
environment:
- AppSettings__UpperTemperatureThreshold=70
- AppSettings__LowerTemperatureThreshold=55
image: mu88/raspifancontroller:latest-chiseled
ports:
- 127.0.0.1:5000:8080
volumes:
- /sys/class/thermal/thermal_zone0:/sys/class/thermal/thermal_zone0:ro # CpuTemperature needs this
devices:
- /dev/gpiomem With this, I can even use the new chiseled base image. Thank you all very much for your help, I really appreciated it! |
Perfect! And if you're willing to document his with a PR, that would be amazing! |
Oh, I'd be glad to do so 😊 where would you like to see this and which content? |
Amazing! I would say here: https://github.com/dotnet/iot/tree/main/Documentation We already have bunch of useful articles to set things up properly . So I guess it will be a nice addition. |
Hi @Ellerbach 👋🏻 I've created this first draft - would you mind having a look whether it matches your expectations and Microsoft's quality standards? If the draft is mature enough, I'd be happy to file a PR where we could discuss the details that might need to be adapted. |
Thanks @mu88, it is very clear all up! Maybe you can add a point on how to install docker/moby on the Raspberry Pi. |
…spberry Pi Relates to dotnet#2169
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 :
Steps to reproduce
dotnet publish RaspiFanController/RaspiFanController.csproj --os linux --arch arm64 /t:PublishContainer
docker-compose.yml
:Expected behavior
The GPIO pin can be accessed.
Actual behavior
The following exception occurs:
Versions used
dotnet --info
: the project was built using a GitHub Action using .NET 8 and the SDK Container Building Toolsdotnet --info
: the app is running inside a Docker container using .NET 8System.Device.Gpio
package:3.0.0
Iot.Device.Bindings
package:3.0.0
CC: @baronfel (maybe interesting for you as well)
The text was updated successfully, but these errors were encountered: