Node-RED integration: Give Docker container access to USB ports

I’m going to restart from scratch to confirm that I have the privileges, because I’ve deleted and re-added so many commands that I’d rather try again.
But I’m pretty sure that originally I used the command you validated for me and therefore there’s no connection to the serial Node
here is the command :

I’ll get back to you :wink:

Good evening @pierre-gilles

@Psoy I just found this (maybe you already have): https://stackoverflow.com/questions/24225647/docker-a-way-to-give-access-to-a-host-usb-or-serial-device
You need to scroll down to The Safe and Proper way of accessing tty devices without *--privileged* mode
Reading the rest it looks pretty good but I don’t have anything to test at home, so we’ll see how it works on your host.
Basically, each time you replug your rflink, a script runs to attach

Good evening @mutmut
I didn’t see what you found, I worked with Gemini to understand why the serial

@Psoy As which user are you launching the Gladys container?

If you want the --privileged to work, the user must be root.

I think that’s not the case on your system!

Are you indeed running sudo docker run... ?

Indeed I wasn’t typing sudo before docker run :worried:.
So I retyped the docker run command with sudo in front, and I repeated the procedure three times to be sure, but even with sudo the permissions of the USB0 port don’t change and remain as follows

crw-rw---- 1 root dialout 188,  0 Feb 21 09:59 /dev/ttyUSB0
lrwxrwxrwx 1 root root          7 Feb 21 09:59 /dev/tty-usb-arduino

That’s normal, the permissions of the USB0 port are supposed to stay like that.

The permissions here show that the user « root » is the owner of this USB port; but if you started your container as root, you should therefore be the owner of the USB port.

Now, you only started the Gladys container, and the Node-RED container was started by Gladys. Maybe the Node-RED container wasn’t started as root.

Can you check which user started the Gladys container, and compare it with the user that started the Node-RED container?

(I’ll let you use Google/AI to find the right commands to do that :slight_smile: )

ah yes that’s how you learn :wink: :joy:

From what I just tested, all the commands are run on the host, not inside the Gladys Docker.
First your Gladys and Node-RED Docker containers must be running.
Then to see if it works you can test:
docker ps -qf name=node-red
and it should return a number/id (that of your Node-RED docker).
If that’s not the case, we won’t continue and you can check if the dockers are running with docker ps

So on the host, you can create (with your preferred text editor):
sudo nano /etc/udev/rules.d/99-docker-tty.rules
then copy/paste:

ACTION=="add", SUBSYSTEM=="tty", RUN+="/usr/local/bin/docker_tty.sh 'added' '%E{DEVNAME}' '%M' '%m'"
ACTION=="remove", SUBSYSTEM=="tty", RUN+="/usr/local/bin/docker_tty.sh 'removed' '%E{DEVNAME}' '%M' '%m'"

If it’s nano, do ctrl+X and Y (or O) and Enter to save and exit.
Then to apply the rules:

sudo udevadm control --reload

Finally you need to create the script that will automatically mount and unmount the device on the USB port:
sudo nano /usr/local/bin/docker_tty.sh
and paste:

#!/usr/bin/env bash  
                                                          
echo "Usb event: $1 $2 $3 $4" \u003e\u003e /tmp/docker_tty.log       
if [ ! -z "$(docker ps -qf name=node-red)" ]                                    
then                                                                           
if [ "$1" == "added" ]                                                         
    then                                                                       
        docker exec -u 0 env_dev mknod $2 c $3 $4                              
        docker exec -u 0 env_dev chmod -R 777 $2                               
        echo "Adding $2 to docker" \u003e\u003e /tmp/docker_tty.log               
    else                                                                       
        docker exec -u 0 env_dev rm $2                                         
        echo "Removing $2 from docker" \u003e\u003e /tmp/docker_tty.log           
    fi                                                                         
fi 

Set the execution rights on this script:
sudo chmod +x /usr/local/bin/docker_tty.sh
And you can then see what happens by plugging in your USB device (notably in /tmp/docker_tty.log).

If nothing works, there’s a command to run but I don’t know exactly what it does (I have my limits :wink: ):
docker run --device-cgroup-rule='c 188:* rmw' -itd --name my_container ubuntu
And that’s what my link indicates to do first. I think it launches an Ubuntu with a container that will be named my_container and we pass it an argument. However, I don’t know whether to run this command on the Gladys docker or on the Node-RED docker, and knowing that the Node-RED docker will be started, I don’t know if it will work …
Anyway, it can get stuck at that point.

In any case, tell me whether the first tests are conclusive.

EDIT: after that I’d be tempted to tell you not to go through Gladys to create/launch the Node-RED docker but to create one separately and then you can run the odd command in that docker.

Good evening @pierre-gilles @mutmut
Can you confirm that the image name of the gladys- node-red container is indeed nodered/node-red:3.1?

CONTAINER ID   IMAGE                                       COMMAND                  CREATED         STATUS                   PORTS                                       NAMES
702448e6dba6   nodered/node-red:3.1                        \"./entrypoint.sh\"        5 minutes ago   Up 5 minutes (healthy)   0.0.0.0:1881-\u003e1880/tcp, :::1881-\u003e1880/tcp   gladys-node-red
e000d717481c   gladysassistant/gladys:node-red-usb-ports   \"docker-entrypoint.s…\"   7 minutes ago   Up 7 minutes                                                         gladys
c12621b8b474   containrrr/watchtower                       \"/watchtower --clean…\"   4 weeks ago     Up 9 minutes (healthy)   8080/tcp                                    watchtower

first I have to initialize the permissions (with CHMOD) because at startup they are not correct
I just tried unplugging and replugging the rflink several times but it doesn’t work, it doesn’t reconnect by itself.
I’m pasting the logs from /tmp/docker_tty.log

pi@rasp3b:/tmp $ sudo nano docker_tty.log
  GNU nano 5.4                                                            docker_tty.log
Usb event: added /dev/tty14 4 14
Usb event: added /dev/tty15 4 15
Usb event: added /dev/tty16 4 16
Usb event: added /dev/tty17 4 17
Usb event: added /dev/tty18 4 18
Usb event: added /dev/tty20 4 20
Usb event: added /dev/tty2 4 2
Usb event: added /dev/tty22 4 22
Usb event: added /dev/tty24 4 24
Usb event: added /dev/tty19 4 19
Usb event: added /dev/tty21 4 21
Usb event: added /dev/tty23 4 23
Usb event: added /dev/tty25 4 25
Usb event: added /dev/tty26 4 26
Usb event: added /dev/tty27 4 27
Usb event: added /dev/tty29 4 29
Usb event: added /dev/tty28 4 28
Usb event: added /dev/tty3 4 3
Usb event: added /dev/tty30 4 30
Usb event: added /dev/tty31 4 31
Usb event: added /dev/tty32 4 32
Usb event: added /dev/tty33 4 33
Usb event: added /dev/tty34 4 34
Usb event: added /dev/tty35 4 35
Usb event: added /dev/tty36 4 36
Usb event: added /dev/tty37 4 37
Usb event: added /dev/tty38 4 38
Usb event: added /dev/tty39 4 39
Usb event: added /dev/tty4 4 4
Usb event: added /dev/tty40 4 40
Usb event: added /dev/tty41 4 41
Usb event: added /dev/tty42 4 42
Usb event: added /dev/tty43 4 43
Usb event: added /dev/tty44 4 44
Usb event: added /dev/tty45 4 45
Usb event: added /dev/tty46 4 46
Usb event: added /dev/tty47 4 47
Usb event: added /dev/tty48 4 48
Usb event: added /dev/tty49 4 49
Usb event: added /dev/tty5 4 5
Usb event: added /dev/tty50 4 50
Usb event: added /dev/tty51 4 51
Usb event: added /dev/tty52 4 52
Usb event: added /dev/tty53 4 53
Usb event: added /dev/tty54 4 54
Usb event: added /dev/tty55 4 55
Usb event: added /dev/tty56 4 56
Usb event: added /dev/tty57 4 57
Usb event: added /dev/tty58 4 58
Usb event: added /dev/tty59 4 59
Usb event: added /dev/tty6 4 6
Usb event: added /dev/tty60 4 60
Usb event: added /dev/tty61 4 61
Usb event: added /dev/tty62 4 62
Usb event: added /dev/tty63 4 63
Usb event: added /dev/tty7 4 7

I don’t see a ttyUSB port, does that ring a bell?
I unplugged my Rflink several times.

I tried passing this command --device-cgroup-rule='c 188:* rmw' in the docker run, but it still doesn’t give permissions to the USB ports.

Then I added this command --device=/dev/ttyUSB0 \\ to the
docker run and that gives permissions to the USB port and the serial node connects fine.
However, it’s the same when we unplug the rflink: the USB port loses those permissions and reverts to crw-rw---- 1 root dialout 188, 0 Feb 21 22:52 /dev/ttyUSB0 instead of crw-rw-rw- 1 root dialout 188, 0 Feb 21 22:52 /dev/ttyUSB0

yes that’s correct.

So you should add your chmod in the script that keeps the variables, and if that doesn’t work, replace chmod a+rw $2 with chmod a+rw /dev/ttyUSB0 hard-coded:

#!/usr/bin/env bash  
                                                           
echo \"Usb event: $1 $2 $3 $4\" >> /tmp/docker_tty.log       
if [ ! -z \"$(docker ps -qf name=gladys-node-red)\" ]                                    
then                                                                            
if [ \"$1\" == \"added\" ]                                                         
    then
        chmod a+rw $2                                                                         
        docker exec -u 0 gladys-node-red mknod $2 c $3 $4                               
        docker exec -u 0 gladys-node-red chmod -R 777 $2                                
        echo \"Adding $2 to docker\" >> /tmp/docker_tty.log                
    else                                                                        
        docker exec -u 0 gladys-node-red rm $2                                          
        echo \"Removing $2 from docker\" >> /tmp/docker_tty.log            
    fi                                                                          
fi 

EDIT: oops, I forgot to change env_dev to gladys-node-red in the script, it must not have been working well :confused:

hello @mutmut
What do $1 $2 $3 $4 represent?

looking at the script that writes to the tmp, I’d say:
Usb event: added /dev/tty40 4 40
$1 = added (or removed)
$2 = /dev/tty40
$3 = 4
$4 = 40
However, no idea what $3 and $4 represent.

We should see /dev/ttyUSB when running lsusb but it won’t appear in the script’s log (and it will be a symbolic link if I’m not mistaken).

for me the symbolic link is this

 /dev/tty-usb-arduino-nano 

which points to /dev/ttyUSB0

Great, it works, I’ll do some tests tonight, but apparently by unplugging and replugging the Rflink, it disconnects and reconnects :clap:

2 Likes

Is this solution going to be added to Gladys?

I uninstalled Gladys and Node-RED then reinstalled them, but I did not delete the two files that were created. After reboot the RFLink reconnects correctly.
I tested on a Raspberry 3B+. Will this solution work on a mini PC?

1 Like

Good news!

For the script, I grabbed it for Debian on PC, so if it works on your Raspberry Pi, there’s no reason it shouldn’t.

2 Likes