# Printserver A containerized CUPS print server that shares a **Brother HL-4150CDN** network printer over IPP and advertises it via AirPrint (mDNS/DNS-SD), so client devices can print without installing the Brother driver themselves. The container bundles: - CUPS (IPP/IPP Everywhere + web admin on port 631) - Avahi / DNS-SD for AirPrint discovery (UDP 5353) - The Brother HL-4150CDN LPR + CUPS wrapper drivers and 32-bit runtime libs ## Layout | Path | Purpose | | --- | --- | | `Containerfile` | Image definition (Debian base, i386 multiarch, Brother driver install) | | `cupsd.conf` | Container CUPS configuration (listen on all interfaces, share printers) | | `entrypoint.sh` | Starts D-Bus, Avahi and CUPS, then registers the printer queue | | `assets/Brother HL-4150CDN/` | Brother driver `.deb` packages used at build time | ## Prerequisites - Podman (or a compatible builder such as Docker/Buildah) - The printer reachable on the network, with a known IP address or hostname ## Build Run from the repository root: ```sh podman build -t printserver:latest . ``` On an arm64 host, build for x86_64 explicitly (the Brother binaries are i386 and need an x86_64 target): ```sh podman build --platform linux/amd64 -t printserver:latest . ``` The build installs the Brother LPR and CUPS wrapper packages from `assets/Brother HL-4150CDN/` and verifies that the PPD and filter are in place. ## Run mDNS does not work through a normal container network, so use **host networking**: ```sh podman run -d --name printserver \ --network host \ -e PRINTER_IP=192.168.1.50 \ -e PRINTER_NAME=HL-4150CDN \ printserver:latest ``` ### Environment variables | Variable | Default | Description | | --- | --- | --- | | `PRINTER_IP` | *(empty)* | IP address / host name of the network printer. A device URI is derived from it (see `PRINTER_PROTOCOL`). | | `PRINTER_URI` | *(empty)* | Full device URI. Overrides `PRINTER_IP` when set. | | `PRINTER_PROTOCOL` | `lpd` | Protocol used with `PRINTER_IP`: `lpd`, `socket` or `ipp`. | | `PRINTER_NAME` | `HL4150CDN` | CUPS queue name. Also used as the name advertised via AirPrint/DNS-SD. | | `PRINTER_DESCRIPTION` | *(empty)* | CUPS printer description (`lpadmin -D`), shown in the CUPS web UI. | | `PPD_FILE` | `/usr/share/cups/model/brhl4150cdn.ppd` | PPD used for the queue. | No queue is created when neither `PRINTER_IP` nor `PRINTER_URI` is set. ### Choosing the connection The HL-4150CDN is a network printer. Set `PRINTER_IP` and let the entrypoint build the URI: | `PRINTER_PROTOCOL` | Resulting URI | | --- | --- | | `lpd` (default) | `lpd:///binary_p1` — LPR/LPD, the URI Brother documents | | `socket` | `socket://:9100` — raw AppSocket/JetDirect | | `ipp` | `ipp:///ipp/print` | For example, a printer at `192.168.1.50` using LPD: ```sh -e PRINTER_IP=192.168.1.50 ``` Or specify the URI explicitly for full control: ```sh -e PRINTER_URI=lpd://192.168.1.50/binary_p1 ``` ### Advertised name `PRINTER_NAME` is used as the CUPS queue name and as the name clients see in AirPrint discovery. To show a descriptive label in the CUPS web interface, set `PRINTER_DESCRIPTION` (this does not change the advertised name): ```sh -e PRINTER_NAME=HL4150CDN -e PRINTER_DESCRIPTION="Brother HL-4150CDN (Office)" ``` ## Verify Browse the CUPS web interface: ```sh open http://localhost:631/ # printers open http://localhost:631/admin # administration ``` From the host, or inside the container: ```sh podman exec printserver lpstat -t # queues and status podman exec printserver lpstat -v HL4150CDN # device URI podman exec printserver avahi-browse -rt _ipp._tcp # mDNS advertisement ``` A print job can be submitted with: ```sh podman exec printserver lp -d HL4150CDN /etc/hostname ``` On macOS/iOS the shared queue should appear in the printer list via AirPrint. ## Notes and limitations - **Run on an x86_64 host.** The Brother driver binaries are 32-bit i386 ELF executables. They run natively on an x86_64 kernel, but on arm64 hosts the image can be built and the drivers installed while the filter cannot execute without i386 emulation (for example qemu-user / binfmt). - **Host networking is required** for Avahi to send and receive mDNS traffic. `-p 631:631` alone is enough for direct IPP access but not for AirPrint discovery. - **Printer state is not persisted.** The queue is recreated on every start from `PRINTER_URI`. To keep CUPS configuration across container replacement, mount a volume over `/etc/cups`: ```sh -v printserver-cups:/etc/cups ``` - The Brother filter is a PostScript-based CUPS filter. AirPrint clients that rely on driverless (URF) printing may not be able to use the queue; macOS clients that can use the shared CUPS queue's PPD will work. - The Brother driver packages are 32-bit (i386); the image enables Debian's i386 multiarch to provide `libc6:i386` and the `ld-linux.so.2` loader they need.