Files
juergen adaa11e416 Archive the add-cups-printserver-container change
Moves the completed change to openspec/changes/archive/2026-10-18-add-cups-printserver-container/ and syncs the printserver/cups capability into openspec/specs/.
2026-10-18 16:54:54 +02:00

5.1 KiB

Design

Context

See proposal.md. We need a Podman container that runs CUPS for the Brother HL-4150CDN network printer and shares it over IPP/AirPrint.

Facts established while exploring the device at 192.168.100.7:

  • The printer is a Brother HL-4150CDN (Ver.1.22) with PCL6 and BR-Script3 (PostScript 3) emulation — @PJL INFO CONFIG lists POSTSCRIPT.
  • Open services: :9100 (raw/AppSocket), :515 (LPR/LPD), :631 (IPP/IPPS) and :80 (Brother web UI). It has one paper cassette plus the MP tray.
  • A raw PostScript job sent to :9100 is interpreted by the printer, and a full CUPS job with Duplex=DuplexNoTumble BRPrintQuality=Color printed correctly (duplex, colour).

An earlier iteration used Brother's Linux packages. That vendor CUPS chain is broken in debian:bookworm-slim: filterhl4150cdn needs file (and a2ps as a fallback), which are absent, so the filter exits 1 and emits zero bytes. That chain also rasterises locally (Ghostscript → ppmraw → brhl4150cdnfilter) and stores per-queue options in a single global file (brhl4150cdnrc), which is heavy and racy. The packages have since been removed from the repository.

Crucially, the Brother vendor PPD (brhl4150cdn.ppd) cannot be used for direct PostScript because its option values are blank (" "); all option handling lives in the vendor filter. Brother's BR-Script3 PPD, in contrast, encodes every option as PostScript setpagedevice.

Goals / Non-Goals

Goals:

  • Build a working CUPS image for Podman with no 32-bit dependencies.
  • Drive the printer with its native PostScript (BR-Script3) interpreter.
  • Preserve the hardware options the user cares about: paper tray, duplex and colour/mono (plus the other options the PPD exposes).
  • Share the queue over IPP and advertise it via AirPrint.
  • Keep the printer address/name runtime-configurable.

Non-Goals:

  • Managing multiple printers.
  • Sharing via SMB/Samba (Windows uses a client-side Brother driver).
  • Persisting CUPS spool/state beyond the container lifecycle.
  • TLS for the CUPS web interface.

Decisions

Base image and packages

Use debian:bookworm-slim with cups, cups-client, cups-filters, avahi-daemon, avahi-utils, libnss-mdns, dbus, ghostscript and poppler-utils. No dpkg --add-architecture i386 and no Brother .deb packages: the job is converted to PostScript in CUPS and interpreted by the printer, so no vendor binary is needed.

Alternative considered: keep Brother's Linux CUPS wrapper + LPR filter. It provides the same options but requires 32-bit libraries, Ghostscript rasterisation and the missing file/a2ps tools, and it writes options to a single global config file. Rejected.

Print path: direct PostScript via the BR-Script3 PPD

Install Brother's official BR-Script3 PPD as /usr/share/cups/model/BR4150_2.PPD (committed at assets/Brother HL-4150CDN/ppd/BR4150_2.PPD, extracted from the vendor Windows driver) and create the queue with it. CUPS's pstops filter reads the PPD and injects the selected option code (e.g. /BRFeeder, /Duplex, /BRProcessColor, /MediaType) into the job; the PPD's *JCLBegin, *JCLToPSInterpreter and *JCLEnd entries wrap it in PJL. The result is forwarded unchanged to the printer.

A stock PostScript PPD (like CUPS's own generic.ppd) has no *cupsFilter either, and CUPS accepts such PPDs — the printer's native format is application/vnd.cups-postscript.

Device URI

Use raw AppSocket as the default: socket://<ip>:9100. lpd://<ip>/binary_p1 and ipp://… remain available through PRINTER_PROTOCOL/PRINTER_URI.

Client support

  • macOS / iOS / iPadOS: AirPrint → CUPS. The queue advertises image/urf, image/pwg-raster, application/pdf and application/postscript, with urf-supported = V1.4,CP1,W8,PQ4,SRGB24,RS600,DM1,FN3, sides-supported (one-sided/two-sided long/short edge) and color-supported = true.
  • Linux: IPP / IPP Everywhere, or plain IPP with PDF/PostScript.
  • Windows: client-side Brother BR-Script3 Windows driver, pointed at the printer directly or at the shared queue.

Runtime configuration

The printer endpoint and advertised name come from environment variables (PRINTER_IP, PRINTER_PROTOCOL, PRINTER_URI, PRINTER_NAME, PRINTER_DESCRIPTION, PPD_FILE) rather than being baked into the image. The entrypoint derives the URI and runs lpadmin on startup, then shares the queue.

Risks / Trade-offs

  • [Risk] The AirPrint path (URF → PDF → PostScript) relies on cups-filters' rastertopdf; it was not exercised with a real URF job during exploration. macOS/iOS printing should be verified end to end.
  • [Risk] Colour handling now relies on the printer's PostScript RIP rather than Brother's host-side colour tables; output may differ slightly from the vendor raster driver.
  • [Risk] The committed PPD is a Windows PPD and contains no CUPS-specific keys. CUPS accepts it as a PostScript PPD (verified for this CUPS version), but this should be re-checked on CUPS upgrades.
  • [Risk] Avahi needs host networking (or equivalent) to advertise mDNS.
  • [Risk] CUPS state is not persisted; the queue is recreated on every start.