Auto-Mount/Unmount External Storage using UDEV - For single container

Hi,

I have been trying to get my container to automate mounting/unmounting external SSD on each power-cycle, so every time the device is turned on.

I managed to successfully be able to mount the SSD manually running the “mount” command.

However, looking through the documentation:
working-with-dynamically-plugged-devices
mounting-external-storage-media

I am still a little confused…I have prepared the container as follows:

  • Adding privileged: true to your container’s service definition on the docker-compose.yml file.
  • Adding ENV UDEV=on to your container’s Dockerfile.
  • Running the entrypoint as the root user in the container namespace. This is often the default but can be set in your container’s Dockerfile with USER root in the target build stage, or in your docker-compose.yml file with user: root.

I’m not really understanding, where exactly do I create the ‘usb.rules’ files, on the container that I want to use the external storage? The mount and unmount scripts I took from the referenced github repository: balena-storage

The line below confused me, where do I place the COPY commands, I tried putting them in my containers Dockerfile, this copied the rules and scripts into my container however, on a reboot of the device, nothing was being mounted. Am I missing something simple?

Copy both the rules and scripts to your container:

COPY usb.rules /etc/udev/rules.d/usb.rules
COPY scripts /usr/src/scripts

Below is how my dockerfile for the container in questions looks:

FROM python:3.11.9-slim

# Set working directory
WORKDIR /app

# Enable UDEV
ENV UDEV=on

# Install dependencies
RUN apt-get update && apt-get install -y ffmpeg && \
    pip install paramiko

# Copy UDEV rules and scripts
COPY usb.rules /etc/udev/rules.d/usb.rules
COPY scripts /usr/src/scripts

# Make scripts executable
RUN chmod +x /usr/src/scripts/mount.sh /usr/src/scripts/unmount.sh

# Copy python scripts
COPY ftp_icListen_ffmpeg.py .
COPY scp_remote_server.py .

# Copy start script to execute python scripts
COPY start.sh .

# Make start.sh executable
RUN chmod +x start.sh

# Run the startup script
CMD ["./start.sh"]

Below is the docker-compose.yml contents for this service:

my_container:
    build: ./my_container
    privileged: true
    restart: always
    network_mode: host
    user: root
    volumes:
      - data:/usr/src/app/Downloaded_Data
      - test_data:/usr/src/app/Remote_Testing
      - logs_data:/usr/src/app/Logs
volumes:
  data:
    driver: local
  test_data:
    driver: local
  logs_data:
    driver: local

Before changing the volumes to use external storage I wanted to make sure that I can auto-mount on each power-cycle as the device will be turned on for only a specific amount of time, before shutting down, every hour or so.

Apologies if this is a very simple question, I just can’t seem to figure out how to get this working…balenaOS is something new to me.

Thank you!

Hi, one thing to try is to run the container in the host network as by default when using the balena base images they run in a network namespace that prevents udev from receiving events.

However if I might add, my preference for mounting an external volume would be to do it from an unprivileged container by letting the OS run the udev rules and bind mounting the external device as a volume. That is the approach taken here and I personally think it’s a safer approach.

Let us know if any of those suggestions work for you.

1 Like

Thank you for that :grin:

I will try the latter that you suggested and will get back to you about it when I get the chance to test it.

Hi,

Just wanted to let you know this worked perfectly, thank you for the suggestion! :grin:

1 Like