Lets older network scanners and printers show up on Macs, iPhones and iPads with no driver: scanners as AirScan, printers as AirPrint.
Run it on any Linux machine on the same network. It finds the devices itself, bridges the ones Apple can't use, and leaves devices that already support AirScan or AirPrint alone.
This is the one fully supported setup. You need a Linux machine on the same network as the devices, with Docker installed. Nothing to clone or build:
mkdir airbridge && cd airbridge
curl -fsSLO https://raw.githubusercontent.com/tobhoster/airbridge/main/compose.yaml
docker compose up -dWhat this does for you:
- Runs the published image
ghcr.io/tobhoster/airbridge(amd64 and arm64). It includesnetbase,sane-airscanand CUPS. - Fetches Brother's driver on first start. Brother scanners only work through brscan4, which is proprietary and x86-only, so the image doesn't contain it. On amd64, the first start downloads it from Brother, checks its SHA-256 and keeps it in the
airbridge-datavolume; later starts don't download again. If the download fails, airbridge starts without it and tries again on the next start.AIRBRIDGE_BRSCAN4=offskips it. - Uses host networking (
network_mode: host). mDNS doesn't work without it.
Check it is running:
curl http://localhost:8090/healthz # {"status":"ok",...}
curl -s http://localhost:8090/ | grep -o '<td>[^<]*</td>' | head # bridged scannersThen open Image Capture (or Preview → Import from Scanner) on a Mac: the scanner is listed under Shared. Printers appear in the normal Add Printer dialog. On a Mac, dns-sd -B _uscan._tcp should list the scanner. The status page is http://<host>:8090/.
Without Compose, the same image runs with docker run:
docker run -d --name airbridge --network host --restart unless-stopped \
-v airbridge-data:/var/lib/airbridge \
-e AIRBRIDGE_INTERFACES=eth0,eth1 \
ghcr.io/tobhoster/airbridge:latestAIRBRIDGE_INTERFACES is optional. The example is for a host with two network interfaces; leave the line out to use auto.
Build it yourself if you'd rather not pull an image. BRSCAN4=1 (the default for local builds) downloads brscan4 from Brother during the build, checks its SHA-256 and puts it in the image:
git clone https://github.com/tobhoster/airbridge && cd airbridge
docker build -t airbridge:local .
docker run -d --name airbridge --network host --restart unless-stopped airbridge:localRaspberry Pi / ARM. The same Compose setup (the image is multi-arch), but without brscan4: Brother only ships it for x86. Brother scanners are then reached only through WSD, and only if the device supports WSD scanning (the Dell MFP E514dw does; many older Brothers don't). Printing works the same as on x86. Use a Pi 4 or 5 with 64-bit Raspberry Pi OS.
Homebrew on Linux (advanced). Convenient, but you install SANE, sane-airscan, brscan4 and CUPS yourself, so problems are harder to diagnose.
brew install tobhoster/airbridge/airbridge
brew services start airbridgeKubernetes (community, advanced). kubectl apply -k deploy/kubernetes runs the published image. The manifests use hostNetwork: true; don't remove it.
- Docker Desktop on macOS or Windows: it has no real host networking, so mDNS can't reach the LAN.
- Bridged container networks (Docker's default network, Kubernetes pod networks without
hostNetwork): same reason.
Nothing is required. Optional environment variables:
| Variable | Default | Purpose |
|---|---|---|
AIRBRIDGE_NO_SCAN, AIRBRIDGE_NO_PRINT |
— | Hosts, names or IPs never to bridge |
AIRBRIDGE_LOCATION |
host name | Shown on the Mac |
AIRBRIDGE_INTERFACES |
auto |
Comma-separated interfaces to find devices on and serve on. auto finds devices on every LAN interface and serves on the default-route one(s) |
AIRBRIDGE_ALLOW |
LAN subnets | Extra client networks (CIDRs) |
AIRBRIDGE_MODEL_MAP |
built in | Rebadged Brother models, Name=BROTHER-MODEL;… |
AIRBRIDGE_PRINTING |
auto |
off for scanning only |
AIRBRIDGE_PORT |
8090 |
HTTP port |
AIRBRIDGE_BACKEND |
sane |
fake serves a demo scanner |
AIRBRIDGE_GAMMA |
1.0 |
Gamma applied to scans (0.1–10). Below 1 brightens, above 1 darkens; 1.0 passes the scanner's levels through |
AIRBRIDGE_BRSCAN4 |
auto |
Published image only: off skips downloading Brother's brscan4 |
RUST_LOG |
info |
info,airbridge=debug logs every mDNS service seen; add mdns_sd=debug to trace the mDNS library |
Build arguments: BRSCAN4=1 puts brscan4 in the image, runtime downloads it on first start (the published image), 0 leaves it out; PRINTING=0 skips CUPS; PRINTER_DRIVERS picks the driver packages.
- brscan4 crashes without
/etc/protocols(slim images). The image installsnetbase. - Dell and other rebadged Brothers need the Brother model name. The Dell MFP E514dw → DCP-L2540DW mapping is built in.
- Brother models that brscan4 doesn't know are skipped. airbridge checks the model against brscan4's own list (402 models in 0.4.11) and logs
brscan4 does not support <model>. Check yours withdocker compose exec airbridge sh -c "grep -h '\"MFC-9340CDW\"' /opt/brother/scanner/brscan4/models4/*.ini"; no output means brscan4 can't drive it. - Printers on DHCP move. airbridge tracks devices by mDNS name, so a new IP is picked up automatically.
If nothing shows up, check these in order:
- Status page.
http://<host>:8090/lists every device airbridge saw but didn't bridge, and why. - Log. airbridge logs each discovery decision. If nothing has been found 30 s after startup, it warns and names the interfaces it is browsing. To see every mDNS service it hears, set
RUST_LOG=info,airbridge=debugand restart. - Is the device announcing? On the host,
avahi-browse -rt _scanner._tcplists Brother scanners andavahi-browse -rt _ipp._tcplists printers. If the device isn't listed there, airbridge can't see it either. - Interfaces. The log line
mDNS: browsing on these interfacesshows where airbridge looks for devices. Thelisteninglines show where Macs can reach it. If either is missing an interface you need, list your interfaces explicitly, e.g.AIRBRIDGE_INTERFACES=eth0,eth1.
Still stuck? Open an issue; questions are welcome. The form asks for the outputs above.
MIT or Apache-2.0. Brother's brscan4 is proprietary and is not part of this repository or of the published image: the image downloads it from Brother on first start (a local build downloads it during the build), and both check its SHA-256.
Development notes (tests, benchmarks, fuzzing) are in CONTRIBUTING.md.