To locally build the container:
docker build -t tc66c-mqtt .
Using Bluetooth from inside a Docker container is not totally straightforward...
Roughly speaking there are two solutions:
- Disable
bluetoothd
on the host and run it inside a priviliged container — effectively confining the use of Bluetooth to that one container - 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...
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.
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.