A lightweight Go daemon that exposes CUPS printers as AirPrint-compatible printers, enabling iOS and macOS devices to discover and print to them.
iOS Device → mDNS Discovery → Avahi (reads service files)
iOS Device → IPP Print Job → AirPrint Bridge (port 8631) → CUPS → Printer
Daemon → Monitors CUPS → Generates Avahi service files
The daemon:
- Queries CUPS for available printers and their capabilities
- Runs an IPP proxy server that iOS/macOS connects to
- Generates Avahi service files with proper AirPrint TXT records
- Forwards print jobs to CUPS
- Monitors for printer changes and automatically updates advertisements
The IPP proxy approach avoids issues with CUPS access controls, TLS configuration, and hostname resolution that can prevent direct iOS→CUPS printing.
- CUPS (cupsd)
- cups-filters (for URF support)
- Avahi (avahi-daemon)
- D-Bus (required by Avahi)
Download the latest release and run the install script:
# Download and extract
tar -xzf airprint-bridge-*-linux-amd64.tar.gz
cd airprint-bridge-*
# Install (as root)
sudo ./install.shThe install script automatically:
- Detects your OS (Alpine, Debian/Ubuntu, Arch, RHEL/CentOS/Fedora, macOS)
- Installs dependencies (cups, cups-filters, avahi on Linux)
- Installs the binary and config file
- Sets up the appropriate service (OpenRC, systemd, or launchd)
# Install without dependencies (if already installed)
sudo ./install.sh --no-deps
# Install without service files
sudo ./install.sh --no-service
# Uninstall
sudo ./install.sh uninstall
# Show help
./install.sh --helpAlpine (OpenRC):
rc-update add airprint-bridge default
rc-service airprint-bridge startDebian/Ubuntu/Arch/RHEL (systemd):
systemctl enable airprint-bridge
systemctl start airprint-bridgemacOS (launchd):
sudo launchctl load /Library/LaunchDaemons/com.github.wafflethief123.airprint-bridge.plist
sudo launchctl start com.github.wafflethief123.airprint-bridge# Install Go 1.21+
# Clone the repo
git clone https://github.com/WaffleThief123/airprint-bridge.git
cd airprint-bridge
# Build
make deps
make build
# Create distribution packages (requires goreleaser)
make dist # Build binaries only
make dist-all # Build full release with archivesReleases are built using GoReleaser and include binaries for:
- Linux: amd64, arm64, armv6, armv7
- macOS: amd64 (Intel), arm64 (Apple Silicon)
Edit /etc/airprint-bridge/airprint-bridge.yaml:
cups:
host: localhost
port: 631
ipp:
port: 8631 # Port iOS/macOS connects to
monitor:
poll_interval: 30s
avahi:
service_dir: /etc/avahi/services
file_prefix: airprint-
printers:
shared_only: true
exclude:
- PDF_PrinterBy default, media sizes are queried from CUPS. For label printers and other specialty devices, you can override with built-in profiles or custom sizes.
| Profile | Printers | Sizes |
|---|---|---|
zebra-4x6 |
Zebra ZPL printers | 4x6, 4x4, 4x3, 4x2, 2.25x1.25 inch |
dymo-labelwriter |
DYMO LabelWriter | Shipping, address, return address labels |
brother-ql |
Brother QL series | 62x100mm, 62x29mm, 29x90mm, etc. |
rollo |
Rollo thermal | 4x6, 4x4, 4x2 inch |
Profiles are auto-detected by matching printer make/model. You can also assign them explicitly.
media:
- printer: ZTC_ZP_450
profile: zebra-4x6media:
- printer: My_Label_Printer
sizes:
- oe_4x6-label_4x6in
- oe_4x4-label_4x4in
- oe_2x1-label_2x1in
default_size: oe_4x6-label_4x6in# List available printers from CUPS
airprint-bridge --list-printers
# List available media profiles
airprint-bridge --list-profilesQuery your printer's supported sizes from CUPS:
ipptool -tv ipp://localhost/printers/YOUR_PRINTER get-printer-attributes.test | grep mediaavahi-browse -r _ipp._tcpYou should see your printers listed with AirPrint TXT records including URF=, Color=, Duplex=, etc.
ls -la /etc/avahi/services/airprint-*.service
cat /etc/avahi/services/airprint-YourPrinter.servicecurl -v http://localhost:8631/- Open any app with print functionality
- Tap Share → Print
- Your CUPS printers should appear
- Print a test page
# Check CUPS MIME types
grep -i urf /etc/cups/mime.types
# Should include:
# image/urf urf string(0,UNIRAST)- Check Avahi is running:
- Alpine:
rc-service avahi-daemon status - systemd:
systemctl status avahi-daemon
- Alpine:
- Check service files exist:
ls /etc/avahi/services/airprint-* - Check firewall allows mDNS (UDP 5353) and IPP (TCP 8631)
- Verify printer is shared in CUPS
# View logs (systemd)
journalctl -u airprint-bridge -f
# View logs (Alpine)
tail -f /var/log/airprint-bridge.log
# Or run in foreground with debug logging
airprint-bridge --log-level debug --log-format console- Check what CUPS reports:
ipptool -tv ipp://localhost/printers/PRINTER get-printer-attributes.test | grep media - Add a media profile override in config (see Media Size Profiles above)
- Restart the daemon
# Alpine (OpenRC)
rc-service airprint-bridge restart
# systemd
systemctl restart airprint-bridgeSIGTERM/SIGINT: Graceful shutdown (cleans up service files)SIGHUP: Reload configuration and resync printers
MIT