0

We have an internal test system for our multi-platform software library which runs, with its zoo of third-party tools, inside an [Ubuntu] Docker container.

To keep things simple, the host machine AND the Docker container both run as the same user, test_user, fixed as UID 1000/GID 1000; this way volumes can be mapped between the two without issue.

However, I now need the Docker container to be able to access devices on the host machine (e.g. GPIOs). This ONLY seems to work if I run the Docker container specifically as the root user, i.e. this successfully permits access to GPIOs on the host (as evidenced by gpiodetect, which uses the libgpio API that we now want to test):

docker run -t --rm -i -u root --privileged -v /sys:/sys -v /dev:/dev docker_image /bin/bash
root@f1f7ca240c1e:/workdir# gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)

...whereas, if I add test_user to the root group, both inside the Docker container and on the host machine, none of these do:

docker run -t --rm -i -u test_user --privileged -v /sys:/sys -v /dev:/dev docker_image /bin/bash
test_user@57130c86c196:/workdir$ gpiodetect
gpiodetect: unable to access GPIO chips: Permission denied
docker run -t --rm -i -u 1000:1000 --privileged -v /sys:/sys -v /dev:/dev docker_image /bin/bash`
test_user@57130c86c196:/workdir$ gpiodetect
gpiodetect: unable to access GPIO chips: Permission denied

Unfortunately running the Docker container as root, as well as not being desirable, is not an easy option as it messes up the mappings with the host machine (lots of shouts of dubious users from Git and the like).

Is there a way to persuade Docker that the [non-root] user it is running as has root privileges and so can have GPIO access?

FYI, on the host:

host:~ $ groups test_user
test_user: test_user root

...and in the Docker container:

test_user@1716f343e8c7:/workdir$ groups test_user
test_user: test_user root
test_user@1716f343e8c7:/workdir$

2 Answers 2

2

Rather than persuading Docker of anything, just give test_user access to the gpiochips on both the host and docker_image. Then you can run Docker as test_user as before.

Typically on the Pi, the gpios are in the gpio group, so add test_user to that group (adduser test_user gpio), in both the host and the docker_image.

Not sure if that is valid for Ubuntu on Pi though (being a Raspberry Pi OS user myself). If not you will need to setup a group on the gpiochips as well. But as long as test_user has the appropriate permissions to access the gpiochip devices, in both the host and docker image, you should be good.

e.g. this works for me with no root involvement:

pi@devpi4:~ $ docker run -t --rm -i -u test_user --privileged -v /sys:/sys -v /dev:/dev libgpiod_axs gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)

where the libgpiod_axs image is an image with libgpiod installed, and has a test_user who is a member of the gpio group, as is the pi user on the host (who could equally be named test_user). Note that the GID of the group must match in the docker image and host.

4
  • That's an excellent suggestion: before I made test_user a member of just the root group on the host-side in the post above, it was actually a member of the gpio group, however there isn't a gpio group inside the Ubuntu Docker container; I guess I need to do some udev rules magic, a la unix.stackexchange.com/questions/42122/…?
    – Rob
    Jul 5 at 13:43
  • I think the rules you need are in /etc/udev/rules.d/99-com.rules in Raspberry Pi OS, specifically the SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" rule. Jul 5 at 14:40
  • Oh, and you don't need /sys to use libgpiod - in case that is the reason you are importing it into the docker container. Jul 5 at 14:46
  • As noted in @Rob's answer, you don't need the udev rule - docker is just mounting the host /dev in the container. But leaving the comment for reference for anyone unsure where the group/permissions of the gpiochip are generally set on the host. Jul 7 at 1:35
0

@kent-gibson's answer above is the business. To be explicit, I added to our Dockerfile:

RUN groupadd -g 997 gpio &&                                                                   \
    echo SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" >> /etc/udev/rules.d/99-com.rules

...(997 being the ID of the gpio group in the underlying Raspbian OS, I wonder if I even needed the udev rule, just the group IDs to match...?) and then at the end of Dockerfile, where test_user is created I added it to the gpio group and job's a good 'un, the test_user has access to the GPIOs from within the Docker image.

Also, as Kent points out, I removed the /sys mapping into the Docker container as it was entirely unnecessary.

1
  • 1
    Haha, yeah the udev rule isn't not needed as udev is not involved. Docker is mounting the host /dev inside the container so you just need the GIDs on the host and container to match. Jul 7 at 1:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .