Skip to content

Latest commit

 

History

History
115 lines (83 loc) · 3.68 KB

README.md

File metadata and controls

115 lines (83 loc) · 3.68 KB

Docker

Building the Container

To locally build the container:

docker build -t tc66c-mqtt .

Docker and Bluetooth

Using Bluetooth from inside a Docker container is not totally straightforward...

Roughly speaking there are two solutions:

  1. Disable bluetoothd on the host and run it inside a priviliged container — effectively confining the use of Bluetooth to that one container
  2. Communicate with Bluetooth via the host's D-BUS — all of the Bluetooth configuration has to happen outside of the container

Neither solution is optimal: There first one effectively bars the rest of the system (i.e. everything not running in the "Bluetooth" container from using Bluetooth). The second requires most of the Bluetooth configuration to happen on the host (somewhat hampering "plug and play").

The second solution is nonetheless much preferred as it is non-invasive and keeps Bluetooth available to other processes on the host.

Also, playing with the first solution on my Raspberry Pi 4 (i.e. repeatedly switching Bluetooth between host and container) at some point causes the Pi4 UART Bluetooth modem to crash hard, only recoverable by rebooting the system...

N.B. For convenience, the below examples use a Debian-based Node-container; the final container used by the repository is based on Alpine. This might cause some issues with the contents of 📁 node_modules not being portable between the two distros...

Running bluetoothd inside the Container

Again: Not the preferred solution, the information is just here for future reference.

docker run --net=host --cap-add=SYS_ADMIN --cap-add=NET_ADMIN -it \
   -v $PWD:/var/tc66c-mqtt node:12-buster /bin/bash

Both --cap-add are required; alternatively use --privileged (which gives even broader privileges to the container...).

On the host:

sudo service stop bluetooth

Inside the container:

apt update
apt install bluetooth
service dbus start
service bluetooth start

Ensure both dbus-daemon and bluetoothd are running before you continue. Then add /etc/dbus-1/system.d/node-ble.conf (as described in the instructions for node-ble; note that %userid% should be root).

Execute the commands as you would normally do.

Using D-Bus

Courtesy of: edgexfoundry-holding/device-bluetooth-c#15.

I've compared the above AppArmor policy against the current Docker base AppArmor policy (which is somewhat cumbersome as there's no way yet to actually see the active policy).

Further modified the policy to include the additional D-Bus interfaces required by node-ble (based on the contents of 📄 node-ble.conf). I still intend to go through https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorDBus and further refine/confine the policy as I think it affords too much access at the moment...

Still, for now it works:

Add the AppArmor policy (needs to be done after each reboot):

sudo apparmor_parser -r -W ./docker/docker-ble

Then:

docker run \
  -v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket \
  --security-opt apparmor=docker-ble -it -v $PWD:/tc66c-mqtt \
  node:12-buster /bin/bash

And simply execute the command as you would normally do.