Automatically mounting a usb drive in a non-balena base image

Hi all,

I have trawled through all the many posts of UDEV and mounting USB drives. It seems by far the easiest process and well documented one is mounting it in to a Balena base image, with the required env variables set. However, as USB drives cannot currently be shared between containers as volumes, I need to mount it into a standard Alpine image for my particular setup. Is there a process for this?

Docs should be helpful: https://www.balena.io/docs/learn/develop/runtime/#mounting-external-storage-media. tldr; you use mount and fstab.

Thanks, I had seen the docs and they were useful, but not sure they achieved what I am looking for. I should add more detail.

I am looking to achieve the " Sharing mounted devices across containers", in-particular this through helpful tool: https://github.com/balena-io-playground/balena-storage?files=1

The docs you referenced state:

In order to be able to detect external media dynamically you will need to run the container in privileged mode and enable udevd on it. This can be easily done if you are using balena base images by:

  • Adding privileged: true to your container’s service definition on the docker-compose.yml file
  • Adding ENV UDEV=on to your container’s Dockerfile

Maybe I being dimwitted here, but I am not sure what the process would be when not using balena base images. Automation seems to rely on UDEV rules?

Hey there! The UDEV=on environment variable trick is specific to Balena base images, but you can accomplish the same behaviour directly with any base image by installing and configuring udev yourself there

It’s as simple as apk add --no-cache udev in Alpine?

apk add will install it.
You’ll need to also start it.
You can see how it is done in balenalib images here: https://github.com/balena-io-library/base-images/blob/master/balena-base-images/armv7hf/alpine/3.11/run/entry.sh#L37-L48

Presumably this approach is similar to the Balena base image approach in that a drive can only be mounted in one container at a time?

Sorry, I think there might be some misunderstanding.

I am looking to achieve the " Sharing mounted devices across containers", in-particular this through helpful tool: https://github.com/balena-io-playground/balena-storage?files=1

This is currently not possible, the link above says “Note that currently it is not possible to share the mounted device across containers.”.

Presumably this approach is similar to the Balena base image approach in that a drive can only be mounted in one container at a time?

The link I’ve sent in my last message is exactly what the balenalib images do (not similar). This is the balenalib images Dockerfile.

1 Like

To follow up for future readers, here is what I ended up doing. This is by no means the only or even best way to do it.

Rather than start to amend the third party images to be compatible with balena USB configurations, I decided to make the balena images run my chosen image code. The hope being this provides a greater compatibility with Balena as it is using native images and setups, and in theory the third party images enclosed in docker images (i.e. Alpine, Ubuntu) should run fluidly as the very nature of containerising is to create stable environments.

  1. I found an image I was trying to provide USB access to. Docker’s official images are a good place to source from (https://github.com/docker-library?page=1), alternatively, in my instance the official NGINX repo (https://github.com/nginxinc/docker-nginx/blob/master/stable/alpine/Dockerfile).

  2. change the top line ‘FROM alpine:3.10’ to the Balena image 'FROM balenalib/raspberry-pi-alpine:3.10; (changing the raspberry-pi according to the system you require).

  3. This NGINX Dockerfile uses -g 101 as its group for a newly created user, which is also used by NGINX, so change ‘-g 101’ to ‘-g 102’ throughout the NGINX Dockerfile.

  4. docker build from Dockerfile, and you should have a balenalib base for your official image source, which can then support the UDEV=on env flag for USB support and other Balena image features. Don’t forget to include the original Entrypoint ‘/usr/bin/entry.sh’ in your new commands in addition to any set by the third party image.

Of course you could also build these images yourself, run from the Balenalib images and then go through the various apt-get/apk steps, although the official images are written specifically for docker so may provide a better base (and in some instances for some images, overcome more complex setups).

You could also go the route of installing UDEV and modifying the start scripts as proposed above if preferred.

This is only proposed as a temporary solution, pending what it appears to be plans to allow USB drives to be automatically picked up and shared across containers as volumes, which is of course a far better solution.