Simply announcing/advertising an MQTT service via Avahi/mDNS

I have a multi-container app. One of the containers is Mosquitto, running on port 1883.

I’d like to announce/advertise this service via Avahi in the simplest way possible. This would seem to be best done by placing an xml mqtt.service file into the /etc/avahi/services/ folder on the host OS. But that folder is read-only, and besides there would appear to be no way to do this during deployment via Balena Cloud.

So I guess I’m stuck with doing something much more complicated involving avahi, dbus and some Dockerfile shenanigans in a container, but nothing I’ve tried has worked.

All the available examples appear to be old/stale or irrelevant to this use-case - i.e. I’m not running a server written in JavaScript or Python, just trying to advertise the existence of an MQTT broker.

Any ideas?

Here’s the .service file:

<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
 <name replace-wildcards="yes">MQTT on %h</name>
  <service>
   <type>_mqtt._tcp</type>
   <port>1883</port>
  </service>
</service-group>

Hi
Just to confirm -
Are you talking about this particular repo - https://github.com/balena-io-playground/balena-avahi-dbus ?

No. That’s one of the ones I looked at. But at 3 years old and with all the BalenaOS developments since, I disregarded it.

I also looked at this https://github.com/balena-io-playground/avahi-zoo-publisher but although it’s newer, I couldn’t get it to work and besides I really don’t want to be running a container with nodejs just to advertise a service that’s nothing to do with nodejs. Someone else couldn’t get it to work either, and there’s an unanswered, unresolved issue from May 2019.

Hi @jfdi , I am no avahi or DBUS guru, but I think it might be able to accomplish what you want to do with avahi-publish from the container. I think you would just want to do something like the below (assuming a debian based container):

RUN apt-get update && apt-get install avahi-utils

Then in your start up script at run time you run something like:

# enable communication to hostOS dbus
export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

avahi-publish -s $HOSTNAME _mqtt._tcp 1883 "Status=Running" "Version=1.0" &> /dev/null &

Let me know if this is what you are after. I also tried the 3 year old project and indeed it is not working and unmaintained, that is why its in our “playground” account where things are just experiments and not intended to be maintained or looked after.

Thanks @shaunmulligan. I tried this kind of thing with Alpine… I had to replace avahi-utils with avahi-tools to get avahi-publish, but it always gives an error Failed to create client object: An unexpected D-Bus error occurred even if I also install the dbus package.

For the moment I’ve hacked one of my NodeJS containers to include the mdns npm package and advertise the service from there. It’d be lovely to see a working, tried & tested example of how to do this. Others on the forums have asked similar & related but different questions. There seems to have been little or no update to the documentation around this topic since the significant update that included Avahi in BalenaOS.

And I understand the “playground” is full of experimental stuff, but it surely deserves some occasional curation & deprecation, or it becomes a misleading pile of old “used to work this way” stuff.

When you tried that from your avahi container did you also set the export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket to expose the hostOS dbus socket (I assume have as you have it working else where) . I tried it in a debian container and it seemed to work correctly and I could see the correct name and port when I ran avahi-browse from my ubuntu machine.

I will chat to some of the internal hardware hackers and see if they can potentially put together a canonical example of publishing an avahi service and then have maintained and supported in https://github.com/balena-io-examples or https://github.com/balenalabs since that is what we aim to keep curated and stuff.

I agree playground is not ideal but its a bit of a double edged sword for us as if we have strict curation and maintenance policies for our team, they will be far less inclined to hack and put stuff up there. We used to do this and it results in the team just putting stuff in their personal accounts. That is okay, but then our full team looses visibility to all those projects and if one of them becomes popular or more useful later we might not catch that and promote it labs or examples.

That being said we are doing lots or rework on all of our github organisations and trying to better wrangle the nearly 2000 repos that make up our orgs so hopefully things will be better and less misleading in the future.

Yup @shaunmulligan … tried that in the Dockerfile, and also in the docker-compose.yml in the environment: key.

It may just be shenanigans with Alpine packages - but I don’t want to have to reeingineer the whole container to be Debian based, so for now I’ll stick to my NodeJs kludge solution since it results in minimal pollution & technical debt.

Next stop udev rules…

I can imagine with 2000 repos it’s a veritable nightmare. Maybe community involvement could help? Not sure how you’d work it, but you potentially have a lot of “spotters” out here.

Hmm, yeah might be something odd with the mix in alpine versions with whatever version is on the OS, in any case, glad you have a workable solution forward and I will raise internally to get some more official avahi examples.

We definitely would love to have some of the community help maintain things, I know we already have quite a few helping out on some of the lab projects, but worth some thought to help the poor playground ones :slight_smile:

1 Like