5

I'm trying to access the serial port (as a user) in my privileged docker container which is already running, but I'm getting "permission denied" errors, while the permissions should be correctly set. As a minimal reproducible example (assuming serial device is connected to /dev/ttyUSB0):

# start docker container with your user id, give it privileged access and mount /dev
docker run -itd --user $(id -u) --name test --privileged -v /dev:/dev ubuntu
# add user and add it to dialout (not sure if this is necessary as we have privileged access)
docker exec -it --user 0 test sh -c "groupadd -g $(id -g) user && useradd -m -u $(id -u) -g $(id -g) -G dialout user"
# install picocom to test serial connection
docker exec -it --user 0 test sh -c "apt update && apt install -y picocom"
# run picocom on /dev/ttyUSB0 to check if we can open it
docker exec -it test sh -c "picocom /dev/ttyUSB0"

But when trying this I get this error:

FATAL: cannot open /dev/ttyUSB0: Permission denied

It's working fine when I execute the command as root, or when I access the serial device directly in the "docker run" command, but I need to be able to access the serial device from an already running container.

Does anyone know what I'm missing?

wilson1994
  • 93
  • 1
  • 7
  • The third line in that output has the pertinent information. What username is attached to that *"already running container"*? Is that username in the `dialout` group? You might be missing the relationship between users, groups file permissions, and process ownership. – sawdust Aug 31 '21 at 22:35
  • @sawdust thank you for your reply. I'm not sure I understand what you mean. The docker container gets started up with my userid (eg 1000). At the start of the container no username is associated with this userid. Next I create a user in this container with this userid and add it to dialout group. This should mean that this newly created user has permission to open ports no? – wilson1994 Sep 01 '21 at 06:52
  • Use shell command `ps -Af` to see all running processes. Changes to a user account take effect when logging in, so either a logout or reboot is required after being adding to a group. – sawdust Sep 01 '21 at 08:55
  • But when executing "docker exec" you start a new process in the container, which you could view as a "new login", thus including the changes to the user being added to dialout? eg when I print output of ps -Af: `$ docker exec -it test sh -c "ps -Af" ` `UID PID PPID C STIME TTY TIME CMD ` `user 1 0 0 13:42 pts/8 00:00:00 /bin/bash ` `user 296 0 0 13:47 pts/9 00:00:00 sh -c ps -Af ` `user 302 296 0 13:47 pts/9 00:00:00 ps -Af ` – wilson1994 Sep 01 '21 at 13:48
  • *"... which you could view as a "new login", thus including the changes to the user being added to dialout?"* -- Your assumption is not validated by your results. See https://unix.stackexchange.com/questions/6387/i-added-a-user-to-a-group-but-group-permissions-on-files-still-have-no-effect Run sanity checks just prior to accessing serial terminal: (1) check ownership of device: `ls -l /dev/ttyUSB*` , (2) check who is in the dialout group (assuming that dialout is the group owner of the device): `members dialout`, (3) check current user: `whoami`. – sawdust Sep 02 '21 at 01:34
  • Now I see the problem: my host OS is arch and there the serial ports are owned by the uucp group, with group id 987. But inside the ubuntu docker container this group id doesnt match with dialout (20), so ttyUSB0 is not owned by dialout.. – wilson1994 Sep 02 '21 at 11:58

3 Answers3

4

Thanks to @sawdust for pointing me to the answer.

The problem was that I'm running an ubuntu docker container in Manjaro (Arch) OS, and on Arch ttyUSB is owned by uucp (group id 987), while on ubuntu it's owned by dialout (group id 20).

So when mounting /dev/ttyUSB0 into the docker container, it's still owned by gid 987, but in the ubuntu environment this group id is not dialout, so even when adding the user to dialout, the user has no permission to open the serial port.

A quickfix would be to create a group with the correct gid and add your user to it:

docker exec -it --user 0 test sh -c "groupadd -g 987 ttyusb && usermod -a -G ttyusb user"

but it's not a complete solution, as this will only make it work for your combination of host OS and docker OS, and not necessarily for other user with different environments.

wilson1994
  • 93
  • 1
  • 7
0

If it is still relevant, the following solution did work for me:

docker run --gpus all -it --privileged --name [container_name] \
        -v "$(pwd)/..":/home/app \
        -v /dev/bus/usb:/dev/bus/usb \
        -v /dev/ttyACM0:/dev/ttyACM0 \
        [image_container_name] bash

Note that you might not need in your application the "gpu" so you can remove that flag "--gpus all"

Merwanski
  • 29
  • 3
  • Please explain what each of the parameters and flags does. The syntax you've provided (i.e. `--privileged` specified twice) suggests that you do not understand the behavior each flag invokes. – Zak Jul 29 '22 at 23:08
  • Hey @Zak here is a short overview about each flag, note that probably you don't need all of them for your app * --gpus all -it --name [container_name] \ -v "$(pwd)/..":/home/app \ --privileged -v /dev/bus/usb:/dev/bus/usb \ --privileged -v /dev/ttyACM0:/dev/ttyACM0 \ [image_container_name] bash – Merwanski Jul 31 '22 at 21:13
  • Thank you for the prompt reply, I really do appreciate it. I think you misunderstood my request. I am asking you to update your _ANSWER_, and explain why you chose to use each flag you selected. The standard command syntax is made clear by invoking `docker --help`, however, the objectives you were trying to achieve when you composed each argument in the command is not. For example, if you could explain why you chose to add `--privileged` twice, that would be of great interest to me. Another would be to explain why would would mount your current directory as `/home/app`. Please break it down. – Zak Aug 01 '22 at 17:42
  • Hey @Zak ah ok I see what you mean and btw sorry but I see that my previous reply is not complete and part of it is missing ... regarding the new questions * "privileged" flag should be added only once not twice I will update my first answer after this * "mounting current directory as /home/app" it is just to avoid copying my source files inside the container and to be able to continue working on them directly from my PC and still seen by the container (I hope it is clear now) if not let me know – Merwanski Aug 03 '22 at 06:02
0

using "docker run --rm --group-add 986 -it --privileged ... " resolves.

if you call groups, show error but works.

$ groups

dcuser dialout staff groups: cannot find name for group ID 986

986

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 22 '22 at 18:57