Fork from quadportnick/docker-cups-airprint
Use the latest or version# tags to auto choose the right architecture.
This Alpine-based Docker image runs a CUPS instance that is meant as an AirPrint relay for printers that are already on the network but not AirPrint capable.
CUPS registers shared printers directly with Avahi via D-Bus for mDNS/DNS-SD advertisement. When you add a printer in CUPS and mark it as shared, it automatically becomes discoverable by iPhones, iPads, and Macs on your network -- no extra configuration needed.
- Native DNS-SD registration: CUPS now registers printers with Avahi directly over D-Bus, replacing the previous
airprint-generate.pyscript that manually created Avahi service files. This fixes an issue where iOS devices would show duplicate printer entries due to a mismatch between the mDNS service name and the CUPS IPP response. - Removed
/servicesvolume: No longer needed since Avahi service files are no longer generated externally. - Internal D-Bus daemon: The container now runs its own
dbus-daemoninternally to support the native DNS-SD registration above.
Upgrading from an earlier version? Remove
- /var/run/dbus:/var/run/dbusfrom your compose file ordocker runcommand if it's there. Older example configurations (including in previous versions of this README and the upstream fork) included this bind mount. It was harmless pre-v2.0 because the container never started its own bus, but as of v2.0 the container's internaldbus-daemonwill write into that shared directory and clobber the host's system D-Bus socket, breaking host services like systemd, smartd, and management UIs until the container is removed. This is most visible on NAS platforms but affects any host.
/config: where the persistent printer configs will be stored
CUPSADMIN: the CUPS admin user you want created - default is CUPSADMIN if unspecifiedCUPSPASSWORD: the password for the CUPS admin user - default is the same value asCUPSADMINif unspecifiedAVAHI_HOSTNAME: the mDNS hostname Avahi will advertise - default iscups-airprint. Set this to a unique name if you have multiple instances, or if the default conflicts with your host's mDNS daemon (common on NAS devices like UGreen, Synology, etc.)
- Must be run on host network. This is required to support multicasting which is needed for Airprint.
docker run --name cups --restart unless-stopped --net host\
-v <your config dir>:/config \
-e CUPSADMIN="<username>" \
-e CUPSPASSWORD="<password>" \
chuckcharlie/cups-avahi-airprint:latest
services:
cups:
image: chuckcharlie/cups-avahi-airprint:latest
container_name: cups
network_mode: host
volumes:
- ./config:/config
environment:
CUPSADMIN: "<YourAdminUsername>"
CUPSPASSWORD: "<YourPassword>"
restart: unless-stoppedFirst, make sure you've removed any - /var/run/dbus:/var/run/dbus bind mount from your compose (see the upgrade note under Changes in v2.0 above). That's the single most damaging misconfiguration on a NAS and will take down host services like the management UI.
NAS operating systems (TrueNAS Scale, Synology DSM, UGreen NAS OS, QNAP, etc.) typically run their own avahi-daemon on the host to advertise things like SMB shares, Time Machine, and Finder hostname visibility. When this container runs in host networking mode, both Avahi daemons share the host's network stack and can collide. Common symptoms:
bind() failed: Address in usein the container logs, followed byFailed to create IPv4 socket, proceeding in IPv6 only mode. The host's Avahi already owns UDP 5353, so the container only gets IPv6 and most iOS devices never see the printer.- A repeating
Host name conflict, retrying with <hostname>-NNloop in the container logs. The container is trying to register the host's own hostname on mDNS. - Printers work in the CUPS web UI but never show up in AirPrint on iOS/macOS.
Things to try, roughly in order of simplicity:
- Set
AVAHI_HOSTNAMEto a unique value likecups-airprint(the default) ormynas-print. This avoids the hostname-conflict loop. - Disable the host's mDNS/Bonjour service. On TrueNAS Scale this is under Network → Global Configuration. On other NAS platforms look for a Bonjour, Avahi, or mDNS setting. This frees UDP 5353 for the container. Trade-off: the NAS itself will no longer advertise over Bonjour, so Time Machine discovery, Finder hostname visibility, and similar features go away.
- Run the container on a macvlan network instead of host networking. This is the option to reach for if you want to keep the host's own Bonjour working (so you don't have to take the trade-off in option 2). Macvlan gives the container its own MAC and IP on your LAN, so its Avahi is on a different network endpoint from the host's and the two stop fighting over port 5353. I have not tested this setup myself and can't offer specific configuration guidance; one user reported success with it in #42 and the Docker macvlan docs are a reasonable starting point. Macvlan generally requires a wired Ethernet parent interface and does not work over Wi-Fi or on Docker Desktop.
If none of the above works, pinning the image to 1.2.0 is a valid workaround while you sort it out. You'll miss future Alpine / CUPS / Avahi security updates, but the older image advertised through the static service file flow and didn't hit these conflicts as visibly.
- CUPS will be configurable at http://[host ip]:631 using the CUPSADMIN/CUPSPASSWORD.
- Make sure you select
Share This Printerwhen configuring the printer in CUPS.