HostOS socket access from Balena containers

Dear Balena Support Team,

I am reaching out to ask for guidance regarding container-to-host communication on BalenaOS.

We are currently upgrading a project targeting the owa5X device. In order to properly control the specific hardware of this device from within our application container, we need to communicate with a service running on the BalenaOS host via a Unix socket.

When attempting to map this socket into our container via the volumes section in our docker-compose.yml (attempting to mount the host path to the container path), our balena push fails with the following error:

Bind mounts are not allowed

We understand that standard Docker bind mounts are restricted by the Balena cloud builders for security and portability reasons. However, we need a way for our HW service (pmsrv) to communicate with the containers through this specific host socket.

Could you please advise on the recommended “Balena way” to achieve this?

  1. Is there a specific directory on the Host OS that is automatically shared or allowed to be mounted?

  2. Are there specific io.balena.features.* labels we should be using to grant access to a custom host socket, similar to how D-Bus access is granted?

Thank you in advance for your help.

Best regards,

I’m not Balena staff but can speak a bit on how we do similar things in cases where we need to break out of the Balena sandbox to do things that aren’t supported via the standard release build mechanisms.

To answer your questions:

  1. /tmp/balena-supervisor/services/${FLEET_ID}/${SERVICE_NAME} on the host OS gets mounted as /tmp/balena in service containers. (eg /tmp/balena-supervisor/services/12345/broker would be mapped as /tmp/balena in the broker container for fleet 12345). If you place or symlink the host socket there it should be accessible in your service container.
  2. No feature labels are needed for that particular path.

If you do find yourself needing to bind mount a volume outside the usual permitted paths you can do so by setting the io.balena.features.balena-socket label on your service container which will expose the Docker daemon socket as /var/run/balena-engine.sock in your container and set the appropriate environment variables for Docker clients to pick it up.

To bind mount host OS paths we have a two phase startup process for those services. The first phase has Balena start the container as normal, in the second phase the container entrypoint makes use of the Balena Engine socket to find itself and the image being used, then calls the equivalent of balena run -v /path/to/mount:/target ${IMAGE_ID} actual-entrypoint (with some extra hooks to ensure stale containers are deleted if they’re hanging around for whatever reason/shut down the container when the parent container dies).