List hci interfaces with Bluez Hciconfig fails

I am trying to do integration tests with bluetooth in docker. I want to create virtual hci interfaces to connect a virtual BLE IoT device (Zephyr OS built for posix) with my integration tests. The virtual interface is created with the Bumble python package (from google).

My problem is that I want to list my virtual hci interfaces but I get the following error when I run hciconfig

Can’t open HCI socket.: Address family not supported by protocol`

I have read for example that I need to activate CONFIG_BT in the linux kernel but this is a docker container

Do you know how can I use Bluez hciconfig tool inside a docker container ? My goal is to use this in a CI pipeline.

Sure thing! To use the Bluez hciconfig tool inside a Docker container for your Bluetooth integration tests, you need to make sure you have all the necessary Bluetooth support in the container environment. But here’s the deal, Docker containers are like separate islands from the host system, so accessing Bluetooth devices directly from within the container can be a bit tricky.

Alright, here’s a laid-back step-by-step guide to set up Bluetooth support in your Docker container:

  1. Get Bluetooth Working on the Host:

Before you dive into the Docker stuff, make sure Bluetooth is up and running on your main system. You know, load those Bluetooth kernel modules and get that Bluetooth daemon (bluetoothd) fired up.

  1. To let your container play with Bluetooth devices, you need to share your host’s Bluetooth stuff with it. That means you’ll have to mount the host’s Bluetooth socket file and /dev folder into the container. That socket file usually chills at /var/run/dbus/system_bus_socket. Just remember, the location could vary depending on your setup.

So when you run your Docker container, slap in these volume mounts:

docker run -it --rm \
  -v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket \
  -v /dev:/dev \
  your_image_name

That way, the container can tap into the Bluetooth socket and devices on your main system.

  1. In your Dockerfile, make sure you install the Bluez package and any other Bluetooth utilities you need, like hciconfig and hcitool. If you’re into the Debian vibe, you can do something like this:
FROM debian:latest
RUN apt-get update && apt-get install -y bluez

Remember to pick a base image that floats your boat and matches your package manager preference.

  1. Now, here comes the tricky part. To get access to Bluetooth devices, your container may need to feel like a VIP and get some access to the /dev files related to Bluetooth (like /dev/hci0). Usually, you’d run the container with the --privileged flag, but word on the street is, it’s not always safe and secure.

A smarter move is to grant specific permissions to your container for the Bluetooth device. So, do something like this:

docker run -it --rm \
  --device=/dev/ttyUSB0 \
  your_image_name

With this setup, the container can enjoy some quality time with /dev/ttyUSB0, which is usually the Bluetooth HCI device, without going fully privileged and crazy.

  1. Once you’ve got Bluetooth support all set up and your container is up and running, it’s time to party! Try running hciconfig and hcitool inside the container to make sure Bluetooth is playing nice and doing what it’s supposed to do.

Oh, and don’t forget, some Bluetooth operations might need some extra privileges or special kernel configs. So, be mindful of security and what you’re granting access to from within your container. By the way, Docker in Docker (DinD) is often not the way to go for this stuff, so keep that in mind too.

If things get too complicated, maybe you can consider running your Bluetooth tests directly on your main system or look into how k8s could be used to achieve the same.

That seems to be a reasonable solution. However I am using Gitlab for my pipeline.

My pipeline pulls the docker image but as far as I know Gitlab runners do not have a way to access resources from host directly. In this case I would need to set up my Gitlab runner with these permissions

e.g.

gitlab-runner register --docker-devices /my/linux/hardware/interface

The runners are managed by our IT. I was looking for a containarized approach but seems that bluez requires a real hardware interface to work correctly.

My goal is to virtualize the bluetooth interface so I do not need access to external resources from the host that runs docker. The project Bumble from google seems a promising solution for this so I might opt to virtualize the HCI interface over a TCP transport layer

see the issue I posted here in case someone is interested

Oh and in case anyone is wondering why I do not work directly with the hardware or use a RPI as a CI runner, is that I want to do integration tests without real hardware. Testing e.g., a simulated mobile app connected directly to my simulated IoT devices over a virtual bluetooth HCI Interface.