Docker container cannot access dynamically plugged USB devices

Hi @nikunj ,

Just to clarify, what problem are you seeing. I note that in your docker-compose.yml file, the UDEV environment variable and the path to /dev isn’t indented correctly, which is probably causing problems with our Supervisor (or for it to ignore them). These need to be indented as such:

environment:
  - UDEV=1
...
devices:
  - '/dev:/dev'

With those set correctly, I believe your setup should work correctly.

Best regards, Heds

Hi @hedss,

The problem is, when I plug a USB device(USB flash drive) in raspberry pi, it does not detect in the container and in host os.

I want to copy some data from the container to the usb drive.

Thanks,
Nikunj

Hi @hedss,

environment:
  - UDEV=1
...
devices:
  - '/dev:/dev'

This solution does not work.

Thanks,
Nikunj

Hey @nikunj, which base image are you using in the ./nodejs/Dockerfile? I’m asking as the UDEV=1 env var is specific to balenalib base images and is handled by the ENTRYPOINT so if you’re using another base image or overriding the ENTRYPOINT in your dockerfile then you will have to implement the equivalent behaviour yourself

Hi, I am using the balenalib/raspberrypi3-node:10-stretch-run base image.

@nikunj, you docker-compose.yml looks OK. I think the original poster in this thread had found that a key issue was that the Dockerfile for one of their services was overriding the ENTRYPOINT and bypassing the /usr/bin/entry.sh script. A sample entry.sh script is given at the following link – note in particular how it sets the UDEV=‘on’ variable in the app container (in addition to the UDEV=1 variable set in the docker-compose file):

So I’d suggest that you checked (or shared here) your nodejs/Dockerfile, to ensure it runs some similar entry.sh script that sets the UDEV variable. Also, just in case you had not seen it, check this documentation page regarding UDEV and init systems with balenalib images:
https://www.balena.io/docs/reference/base-images/base-images/#how-the-images-work-at-runtime

If we overwrite /usr/bin/entry.sh then can we overwrite the requirements for the the udev and privileged flags being set in the docker-compose.yml?

I’m not suggesting that this overwriting of /usr/bin/entry.sh is wise or without other side effects.

If we overwrite /usr/bin/entry.sh then can we overwrite the requirements for the the udev and privileged flags being set in the docker-compose.yml?

@jason10, do you mean whether it would be possible to have it “working all the same” without setting privileged and UDEV in docker-compose.yml? (Provided you “do what’s needed” in your own overriden entry.sh script.) If that’s what you meant, then I think the answer is:

  • “No” for the priviledged flag, because I believe it is interpreted by balenaEngine regardless of the entry.sh script.
  • “Maybe” (i.e., I don’t really know) :slight_smile: regarding the UDEV variable.

I’m not suggesting that this overwriting of /usr/bin/entry.sh is wise […]

Indeed, let me list a few reasons why I do not think it is wise to skip UDEV=1, even if you could:

  • Even if it worked now, future updates to balenalib images might break it, because you’d be relying in undocumented behaviour (or going against the documented behaviour…)
  • Every time in the future that you shared your docker-compose file with balena support or forums, the first thing that everyone would point out is that you’re missing UDEV=1 in your docker-compose…
  • Even your work colleagues in your company, or consultants or freelancers, would get confused because they’ll see it doesn’t match the documentation. :slight_smile:

Thank you. I was pretty sure that it would be stupid to overwrite /usr/bin/entry.sh for current and future functionality and support.

Same problem here. USB re-plugging does not work. Did you ever find a solution ??

environment:
  - UDEV=1
privileged: true
devices:
  - '/dev:/dev'

Does not work !!! What am I missing ??

This always works for me. Make sure that

  1. You are using an image based on the balena base image
  2. You are not overwriting the ENTRYPOINT statement

Thank you rapha.

My question: what do you mean by overwriting the ENTRYPOINT statement ?

Do I overwrite it by doing the following inside the Dockerfile.template of the parent docker container:

WORKDIR /opt

COPY package.json yarn.lock /opt/
COPY . /opt/
COPY ./src /opt/
RUN yarn build
COPY ./dist /opt/

CMD ["bash", "/opt/start.sh"]

And our start.sh file looks like this:

#!/bin/bash
value="./node_modules/.bin/electron dist/src/main.js --no-sandbox"
echo "STARTING ELECTRON"
exec $value

This only applies if your image derives from a balena image, so your Dockerfile should start with e.g.

FROM balenalib/raspberrypi4-64-ubuntu:focal

The implementation of that base image will define an ENTRYPOINT, e.g. base-images/Dockerfile at master · balena-io-library/base-images · GitHub

Your container will still contain that statement unless you declare it again. That is what I mean by overwrite it.

What you showed in your Dockerfile is fine, but I can’t see the FROM statement at the top.

Thank you for clarifying.

From my understanding I am using an image that derives from a balena image:

Here the FROM inside the main app:

ARG NODEJS_VERSION="16"
FROM balenalib/%%BALENA_MACHINE_NAME%%-node:${NODEJS_VERSION}-run

I had also tried the following - but with an identical result that it won’t work:
FROM balenalib/amd64-debian-node:16

In my service container (sub app), I use the following:

FROM balenalib/%%BALENA_MACHINE_NAME%%-node:16

I am running everything on a HP i3 PC with a GENERIC x86_64 (legacy MBR) device type.

Still does not work. In the meantime I also tried the new version of GENERIC x86_64 (GPT) - but same thing: USB-hotplug-events are not recognized by any balena-docker-container services !

Only network_mode: host works - but this is of no use for me since I absolutely need my container-services in bridge-mode !!

Here are my settings in all my container services. But no success with it.

environment:
  - UDEV=1
privileged: true
devices:
  - '/dev:/dev'

I tried about every node USB-detection library out there. All work locally (or as mentioned with network_mode = host). But as soon as I change to bridge-mode, they don’t work anymore!

I tried:

usb-detection

I tried:

node-usb

I tried:

@balena.io/usb

All without success :frowning:

Any idea how to get the USB-hotplug events propagated to the balena container services at all ?

The solution is described here.

You have to restart the UDEV as bversluijs describes in his solution.

1 Like