Moves the completed change to openspec/changes/archive/2026-10-18-add-cups-printserver-container/ and syncs the printserver/cups capability into openspec/specs/.
5.1 KiB
printserver/cups Specification
Purpose
Provide a containerized CUPS print server that shares the Brother HL-4150CDN network printer as an AirPrint/IPP printer and prints by sending PostScript directly to the printer, so clients can print without a server-side vendor driver.
Requirements
Requirement: Container image builds with required dependencies
The container SHALL include CUPS, cups-filters, Avahi/mDNS, D-Bus and the conversion tools needed to turn client documents into PostScript, and SHALL NOT require any 32-bit runtime libraries.
Scenario: Image contains CUPS
- WHEN the image is built
- THEN CUPS is installed and available at /usr/sbin/cupsd
Scenario: No 32-bit runtime required
- WHEN the image is built
- THEN the image contains no i386 multiarch libraries and no Brother vendor binaries
Requirement: Brother BR-Script3 PPD is installed
The container SHALL install Brother's official HL-4150CDN BR-Script3 PPD from the committed asset so CUPS can emit device options as PostScript.
Scenario: PPD present
- WHEN the image is built
- THEN the BR-Script3 PPD is present in the CUPS model directory
Scenario: CUPS recognises the model
- WHEN the queue is created with the PPD
- THEN CUPS reports the printer make and model as "Brother HL-4150CDN BR-Script3"
Requirement: Hardware options are sent to the printer
The system SHALL translate the PPD's device options into PostScript
setpagedevice instructions so the printer's own hardware options are used.
Scenario: Paper source
- WHEN a job selects an input slot (auto select, a tray or the MP tray)
- THEN the emitted PostScript selects the corresponding paper source on the printer
Scenario: Duplex
- WHEN a job selects long-edge or short-edge two-sided printing
- THEN the emitted PostScript sets
/Duplexand/Tumbleaccordingly
Scenario: Colour or mono
- WHEN a job selects colour or mono
- THEN the emitted PostScript sets the corresponding colour/mono device parameters
Requirement: Jobs are printed via direct PostScript
The container SHALL forward the converted job as PostScript to the printer without a server-side vendor filter or host-side rasterisation.
Scenario: Default device URI
- WHEN the container is started with a printer IP and no explicit URI
- THEN the queue is created with a raw AppSocket URI (
socket://<ip>:9100)
Scenario: A job is printed
- WHEN a print job is submitted to the queue
- THEN the job is delivered to the printer as PostScript and printed by the printer's PostScript interpreter
Requirement: Printer is shared and discoverable
The system SHALL share the queue over IPP and advertise it via AirPrint (mDNS/DNS-SD).
Scenario: IPP printer is shared
- WHEN CUPS runs in the container
- THEN the printer is shared via IPP for network clients
Scenario: AirPrint discovery
- WHEN Avahi runs alongside CUPS
- THEN the printer is advertised via AirPrint with URF, sides and colour capabilities so macOS and iOS/iPadOS clients can discover it without a driver
Requirement: Supported client platforms
The shared printer SHALL be usable from macOS, iOS/iPadOS, Linux and Windows.
Scenario: macOS and iOS/iPadOS
- WHEN a macOS or iOS/iPadOS client prints via AirPrint
- THEN the job is converted to PostScript and printed
Scenario: Linux
- WHEN a Linux client prints over IPP
- THEN the job is converted to PostScript and printed
Scenario: Windows
- WHEN a Windows client prints
- THEN it uses a client-side BR-Script3 driver against the printer or the shared queue
Requirement: Runtime configuration is exposed
The container SHALL expose CUPS on port 631 and mDNS on UDP port 5353.
Scenario: CUPS port exposed
- WHEN the container runs
- THEN port 631 is available for CUPS administration and IPP
Scenario: mDNS port exposed
- WHEN the container runs
- THEN UDP port 5353 is available for AirPrint discovery
Requirement: Printer endpoint and advertised name are configurable at runtime
The container SHALL accept the network printer address and the advertised printer name through environment variables so the same image can target a different printer or name without rebuilding.
Scenario: Printer IP is provided
- WHEN the container is started with
PRINTER_IPset - THEN a device URI is derived from that address and the Brother HL-4150CDN queue is created pointing at it
Scenario: Printer protocol is selected
- WHEN the container is started with
PRINTER_IPandPRINTER_PROTOCOL - THEN the device URI uses that protocol (socket, lpd or ipp), defaulting to socket
Scenario: Full URI override
- WHEN
PRINTER_URIis set - THEN it is used as the device URI and
PRINTER_IPis ignored
Scenario: Custom advertised name
- WHEN the container is started with
PRINTER_NAME - THEN the CUPS queue uses that name and it is the name advertised via AirPrint/DNS-SD
Scenario: Custom CUPS description
- WHEN the container is started with
PRINTER_DESCRIPTION - THEN the queue's CUPS Description (Info) is set to that value