How to mount SD card in docker?

I am trying to access the SD card from docker, on Torizon. The docker also runs a GUI and enables user interaction via mouse. My current docker-compose.yml file contains the following bindings:

volumes:
  - type: bind
    source: /tmp
    target: /tmp
  - type: bind
    source: /var/run/dbus
    target: /var/run/dbus
  - type: bind
    source: /dev
    target: /dev
  - type: bind
    source: /run/udev
    target: /run/udev
  - type: bind
    source: /home/torizon/Program
    target: /home/torizon/Program

However, I cannot see the SD card (nor a USB flash drive) mounted using the lsblk command. If I use the following bindings:

volumes:
  - type: bind
    source: /tmp
    target: /tmp
  - type: bind
    source: /var
    target: /var
  - type: bind
    source: /dev
    target: /dev
  - type: bind
    source: /run/udev
    target: /run/udev
  - type: bind
    source: /home/torizon/Program
    target: /home/torizon/Program

I am able to see and access the removable media, but when I try to install new packages using apt-get, I get the following error:

apt-get install sqlite
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (2: No such file or directory)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?

I’ve also tried with sudo in front, but the result was the same. As seen, the only difference is that in the first case I’ve used /var/run/dbus, whereas in the second case I’ve used /var.

Can someone tell me how to properly configure the docker file/container to access removable media and allow apt-get to work properly?

Thank you again. It worked after adding the /media binding. Can you tell me what are all the device-cgroup-rules for?

Also, in my setup it may be possible to connect the SD card/USB flash drive after the docker has started. In this case, as I understand from you, is it possible that the removable media will not be visible in the container (if so, then how to make it visible)?

The --device-cgroup-rules flag is a more granular approach to the --privileged flag. Instead of granting host wide permissions/privileges to the container we instead only grant access to what we need. I don’t recall what each exact cgroup in that command grants permission to what exactly but I believe they’re mostly related to common interfaces like display, usb, touch and such.

As for having the media propagate properly when removed/mounted there is a special way to do this in Docker. You’ll need to use a special bind-mount with the “propagation” property. More info on this property here: https://docs.docker.com/storage/bind-mounts/#configure-bind-propagation

But in short it’ll look something like this in the docker-compose (assuming /media is the mount point):

volumes:
      - type: bind
        source: /media
        target: /media
        bind:
          propagation: shared

Additionally I’ve had some customers also need the following cgroup addition:

device_cgroup_rules:
      # ... for USB devices
      - "b 8:* rmw"

Though for some reason on my setup I didn’t require this, it may depend on USB drive properties. In any case give this a try in a simple container and see if your media device propagates properly when removed and added while the container is running.

Best Regards,
Jeremias

In my case it works without the propagation: shared property (I’ve removed and inserted the SD card and USB flash drive many times and the /media folder in the container automatically updates every time). Maybe it is because I am running the container in privileged mode. Thank you.

Interesting finding, well glad it does work for you.

Best Regards,
Jeremias

Greetings @CristianM,

I’m unable to reproduce this on my side for reference as a base container I used the basic weston Debian container as documented here: https://developer.toradex.com/knowledge-base/debian-container-for-torizon#Debian_With_Weston_Wayland_Compositor

The full docker run command is as follows:

# docker run -d --rm --name=weston --net=host --cap-add CAP_SYS_TTY_CONFIG              -v
/var/run/dbus:/var/run/dbus -v /media:/media -v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/              --device-cgroup-rule='c 4:* rmw' --device-cgroup-rule='c 13:* rmw'              --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw'              torizon/weston:$CT_TAG_WESTON --developer weston-launch --tty=/dev/tty7 --user=torizon

The command is as documented except for the /var/run/dbus bind-mount to mimic your scenario, and the /media bind-mount which is where my USB drive was mounted. With the above my USB drive is accessible in the container’s /media and apt still works.

As a side note the reason apt fails in your 2nd case is because by bind-mount all of /var you break how apt works. The apt package manager uses files that are maintained in /var by bind-mounting all of /var you override these crucial files which causes apt to fail.

So in your setup is the SD/USB mounted prior to the container starting? If the drive is connected to the system after the container has already started then the drive won’t be propagated properly to the container file system. Other than that I can’t imagine why you aren’t seeing your pre-mounted drive in the container.

Best Regards,
Jeremias