
AVAHI on Yocto: which recipes/packages do I add, and how do I enable avahi-daemon and D-Bus in the image?
Yocto makes it straightforward to ship Avahi as a first-class system service, but you need to pull in the right recipes and wire up both avahi-daemon and D-Bus so mDNS/DNS-SD actually runs on the target. Below is a practical, image-level recipe for getting from “no Avahi” to “Bonjour/Zeroconf-style discovery is running at boot” on a Yocto-based system.
Note: Commands and variables assume a reasonably recent Yocto release with systemd as PID 1. Adjust naming if you’re on older branches or using SysV init.
1. Know what you’re enabling: avahi-daemon + D-Bus
Avahi’s architecture on Yocto looks the same as on any other Linux:
avahi-daemon: the mDNS/DNS-SD daemon that does the actual multicast traffic on the LAN.- D-Bus (usually system bus): the primary API Avahi exposes for browsing and registering services.
- Client tools (
avahi-browse,avahi-publish, etc.): useful for debugging and simple registration. - Optional extras:
- nss-mdns: allows
*.localhostname resolution in “all system programs using nsswitch.” - Avahi libraries: for C clients or bindings in higher-level languages.
- nss-mdns: allows
For most Yocto images, you want at least:
avahi-daemondbus+dbus-daemonnss-mdns(if you expecthostname.localto resolve from generic programs and shells)
2. Add Avahi and D-Bus to your Yocto image
In Yocto, Avahi is supplied by the avahi recipe (in poky or your BSP layer), which in turn produces multiple binary packages. The exact split varies slightly by distro config, but the common pattern is:
avahi-daemon– the daemon and systemd unitavahi-utils–avahi-browse,avahi-publish, etc.avahi-autoipd– link-local IPv4 support (optional)libavahi-*– client libraries (for your own applications)
You normally include packages at the image level.
2.1 Add packages to IMAGE_INSTALL
In your image recipe (e.g., core-image-minimal.bbappend, your-product-image.bb) add:
IMAGE_INSTALL:append = " avahi-daemon avahi-utils dbus"
If you want *.local hostnames via mDNS through nsswitch (highly recommended):
IMAGE_INSTALL:append = " avahi-daemon avahi-utils dbus nss-mdns"
That’s usually enough to pull in all the necessary libraries and dependencies. If your BSP splits D-Bus differently, you may need dbus-daemon instead of plain dbus, but most default setups pull the daemon when you add dbus.
2.2 Ensure you have the right layer and recipe
Verify the Avahi recipe is available:
bitbake-layers show-recipes | grep -i avahi
You should see something like:
avahi:
avahi_0.8.bb ...
If you don’t see it:
- Add
meta-networkingor another layer that shipsavahi, depending on your Yocto version and vendor BSP. - Then rerun
bitbake-layers show-recipesto confirm.
3. Enable D-Bus on the target image
Avahi’s primary API is D-Bus and “required for usage of most of Avahi.” On systemd-based Yocto images, D-Bus integration looks like this:
- Install D-Bus packages (already handled by
IMAGE_INSTALL:append = " dbus"). - Ensure systemd services for D-Bus are enabled (this is typically automatic when systemd is your init system).
- For more explicit control, you can add D-Bus to
DISTRO_FEATURESif your distro is extremely stripped down.
3.1 Check DISTRO_FEATURES
In conf/distro/<your-distro>.conf (or local.conf for local experimentation), confirm:
DISTRO_FEATURES:append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
D-Bus doesn’t have to be in DISTRO_FEATURES itself; pulling in the dbus package is usually enough. But systemd-based images will then start the D-Bus service at boot.
4. Enable avahi-daemon as a systemd service
Yocto’s avahi recipe typically installs avahi-daemon.service and enables it via the standard systemd conventions once the package is installed. Still, it’s common to make the enablement explicit.
4.1 Use SYSTEMD_AUTO_ENABLE
If you’re writing a custom recipe for your own image or meta-layer, you can explicitly enable Avahi’s systemd unit in the recipe that depends on it:
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE:${PN} += "avahi-daemon.service"
If you prefer to keep systemd configuration in the image recipe, you can also use IMAGE_INSTALL plus systemd’s preset mechanisms, but SYSTEMD_AUTO_ENABLE is the straightforward way when a package ships the unit.
4.2 Verify at runtime
On the target, check:
systemctl status avahi-daemon
You should see something like:
Loaded: loaded (/lib/systemd/system/avahi-daemon.service; enabled; ...)
Active: active (running)
If it’s not running:
systemctl enable avahi-daemon
systemctl start avahi-daemon
If these commands fail, double-check:
avahi-daemon.serviceexists under/lib/systemd/systemor/etc/systemd/system.- The package
avahi-daemonis actually present on the rootfs (useopkg list-installed | grep avahior the appropriate package manager for your image).
5. Optional but recommended: nss-mdns for *.local resolution
The Avahi docs explicitly point to nss-mdns as the component that lets “hostname lookup of *.local hostnames via mDNS in all system programs using nsswitch.” On Yocto, treat this as a separate package:
5.1 Add nss-mdns to the image
IMAGE_INSTALL:append = " nss-mdns"
5.2 Configure /etc/nsswitch.conf
Ensure the hosts line includes mdns (or mdns4/mdns6) before or alongside dns. Example:
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
On some Yocto images, the nss-mdns package installs a sample nsswitch.conf fragment. If not, you may need to adjust it via:
- A custom
ROOTFS_POSTPROCESS_COMMAND, or - A small configuration recipe that installs a specific
nsswitch.conf.
5.3 Test resolution
On the target:
ping hostname.local
If hostname.local corresponds to a machine advertising via Avahi/Bonjour on your LAN, it should resolve. If it doesn’t:
- Confirm
avahi-daemonis running on that host. - Check your
nsswitch.confordering. - Use
avahi-browse -ato see if services and hostnames appear at all.
6. Minimal Yocto configuration example
Here’s a small, concrete configuration set that takes a systemd-based Yocto image from “no Avahi” to “mDNS/DNS-SD enabled at boot”:
6.1 In conf/local.conf (or your distro config)
DISTRO_FEATURES:append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
6.2 In your image recipe, e.g., my-avahi-image.bb
DESCRIPTION = "My Yocto image with Avahi/mDNS support"
LICENSE = "MIT"
inherit core-image
IMAGE_INSTALL:append = " \
avahi-daemon \
avahi-utils \
dbus \
nss-mdns \
"
If you want to be explicit about systemd service enablement inside an additional package recipe you own:
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE:${PN} += "avahi-daemon.service"
Build the image:
bitbake my-avahi-image
Flash/run it, then on the target:
systemctl status dbus
systemctl status avahi-daemon
avahi-browse -a
You should see mDNS traffic and discovered services.
7. Using the Avahi APIs on Yocto
Once avahi-daemon and D-Bus are in place, your applications talk to Avahi exactly as they would on any other Linux box.
The Avahi docs describe three main APIs:
-
D-Bus API (recommended):
“An extensive D-Bus interface for browsing and registering mDNS/DNS-SD services using avahi-daemon. We recommend using this API for software written in any language other than C (e.g. Python).” -
C client libraries (
libavahi-client,libavahi-common):
For native C integration with the running daemon. -
Embedded stack API (not recommended for normal desktops):
Only for embedded appliances that need to embed the full mDNS stack; avoid running multiple stacks on a single host.
On Yocto, nothing changes here: the system bus is available, and /etc/avahi/services works the same way for static XML registrations.
7.1 Static service publication via /etc/avahi/services
If you want a service on your Yocto device to be advertised without a custom publisher:
-
Install a service definition:
<!-- /etc/avahi/services/my-http.service --> <service-group> <name replace-wildcards="yes">%h HTTP</name> <service> <type>_http._tcp</type> <port>80</port> </service> </service-group> -
Ensure
avahi-daemonis running. -
From another machine, run
avahi-browse -aor use a Bonjour client; you should see<hostname> HTTPon_http._tcp.
Yocto’s rootfs build will include this file if you add it via a recipe (e.g., SRC_URI with install in do_install()).
8. Common Yocto-specific pitfalls
A few recurring issues when integrating Avahi on Yocto-based systems:
-
Avahi installed but not running
- Cause: systemd is not configured as
VIRTUAL-RUNTIME_init_manager, oravahi-daemon.serviceisn’t enabled. - Check:
ps aux | grep avahi-daemon,systemctl status avahi-daemon.
- Cause: systemd is not configured as
-
D-Bus not available
- Cause: stripped-down image without
dbuspackage, or wrong init system. - Symptom: clients using Avahi’s D-Bus API fail to connect to the system bus.
- Cause: stripped-down image without
-
hostname.localdoesn’t resolve- Cause:
nss-mdnsmissing ornsswitch.confdoesn’t includemdns. - Fix:
IMAGE_INSTALL:append = " nss-mdns"and updatehosts:line.
- Cause:
-
Multiple mDNS stacks accidentally running
- Cause: embedded application linking the Avahi “full mDNS/DNS-SD stack” directly while
avahi-daemonalso runs. - Fix: for standard Yocto systems, use the D-Bus API or C client library against
avahi-daemon; avoid running a second mDNS stack.
- Cause: embedded application linking the Avahi “full mDNS/DNS-SD stack” directly while
Final decision framework
On a Yocto image, treat Avahi as a normal system component:
- Add
avahi-daemon,avahi-utils, anddbustoIMAGE_INSTALLto get the daemon and D-Bus. - Add
nss-mdnsif you want*.localresolution in all programs via nsswitch. - Use systemd as the init system and ensure
avahi-daemon.serviceis enabled so mDNS/DNS-SD is running at boot. - Integrate your applications via D-Bus or /etc/avahi/services rather than embedding an extra mDNS stack.
Once these pieces are in place, your Yocto-based devices behave like any other Linux system with Avahi: they can “find printers to print to” and “find files being shared” on the LAN with Bonjour/Zeroconf-compatible discovery.