Add CUPS print server container for Brother HL-4150CDN

This commit is contained in:
juergen committed 2026-10-18 09:16:37 +02:00
commit 6f3162849b
52 files changed
+5168

No files matched your search

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-17
@@ -0,0 +1,62 @@
# Design
## Context
See proposal.md for motivation - we need to create a Podman container that runs a CUPS print server for Brother HL-4150CDN. The repo contains the Brother driver packages in `assets/Brother HL-4150CDN/`:
- `lpr-driver/hl4150cdnlpr-1.1.1-5.i386.deb`
- `cupswrapper/hl4150cdncupswrapper-1.1.1-5.i386.deb`
- `installer/linux-brprinter-installer-2.2.6-0.gz` (reference only; we will NOT run it in the build - it is interactive and downloads from the network)
Key observations:
- Brother drivers are i386 binaries (32-bit ELF). Container needs 32-bit runtime libraries.
- CUPS wrapper + LPR packages provide PPD, filters, and helper binaries.
- AirPrint requires CUPS + Avahi/mDNS (DNS-SD).
- Brother's cups wrapper installs files to /usr/local/Brother/ and may need symlinks into CUPS directories.
## Goals / Non-Goals
**Goals:**
- Create a Containerfile that builds a working image for Podman
- Install and configure Brother HL-4150CDN drivers
- Share printer via IPP with AirPrint discovery
- Expose ports 631 (CUPS/IPP) and 5353/udp (mDNS)
- Make it easy to run with podman
**Non-Goals:**
- Managing multiple printers
- Custom SSL/TLS configuration for CUPS (use defaults or documented)
- Persistent CUPS spool/state beyond basic setup
## Decisions
### Base image
- Use Debian/Ubuntu (or similar) as base to handle .deb packages and 32-bit libs easily. Alternatively Alpine, but Alpine needs musl + 32-bit support can be more complex for prebuilt i386 ELF binaries from Brother. Debian stable is practical.
### Driver installation
- Use the local `.deb` packages from `assets/Brother HL-4150CDN/` (copied into the build context) and install with `dpkg -i --force-all`. No network download at build time for the driver itself.
- Do not run the Brother installer script (`linux-brprinter-installer-2.2.6-0.gz`) in the build - it is interactive and downloads packages from download.brother.com.
- Also need to install brcupsconfpt1 helper if needed - comes with cups wrapper.
- Run the cups wrapper install logic as per Brother installer (or manually create symlinks).
### CUPS + Avahi + DBus
- Install cups, avahi-daemon, dbus. Run dbus and avahi-daemon; start cupsd.
- Configure CUPS to allow remote access/sharing. For containerized setup, typically need to listen on all interfaces and configure sharing.
### Printer configuration
- Add printer via lpadmin using the Brother PPD. Point to network URI (e.g., ipp://PRINTER_IP/ipp or socket://PRINTER_IP:9100 - depends on printer; HL-4150CDN is network printer).
- Enable printer sharing and default options.
### Runtime configuration
- The printer endpoint and advertised name are supplied through environment variables rather than baked into the image, so the same image can be pointed at any HL-4150CDN:
- `PRINTER_IP` + `PRINTER_PROTOCOL` (lpd/socket/ipp) derive the device URI.
- `PRINTER_URI` overrides the derived URI for full control.
- `PRINTER_NAME` sets the CUPS queue name and the DNS-SD/AirPrint advertised name.
- `PRINTER_DESCRIPTION` sets the CUPS Description (Info) shown in the web UI.
- The entrypoint builds the URI and runs lpadmin at startup, then shares the queue.
## Risks / Trade-offs
- [Risk] Brother binaries are 32-bit only → require multiarch libs (libc6:i386, etc.). Increases image size slightly.
- [Risk] Using .deb packages assumes glibc-based base. If we choose different base, need to ensure compatibility.
- [Risk] Avahi in container needs --net=host or proper mDNS setup. AirPrint discovery typically works better with host network mode; document this.
- [Risk] CUPS state (printers.conf, etc.) should be persisted if we want config to survive restarts - may need volumes.
@@ -0,0 +1,29 @@
# Proposal
## Why
Provide a Podman container that runs CUPS and shares the Brother HL-4150CDN network printer as an AirPrint and IPP printer. Clients should be able to print without installing local printer drivers.
## What Changes
- Create a Containerfile for Podman (based on a Linux distro that supports CUPS and 32-bit binaries)
- Extract and install Brother driver files (from `assets/Brother HL-4150CDN/` - local .deb packages: `hl4150cdnlpr` and `hl4150cdncupswrapper`) needed for HL-4150CDN
- Configure CUPS to run in the container and share the network printer
- Enable mDNS/Avahi for AirPrint discovery
- Provide minimal runtime configuration (ports 631, 5353/udp) and documentation for running with podman
- Handle 32-bit dependencies required by Brother i386 binaries
## Capabilities
### New Capabilities
- `printserver/cups`: Containerized CUPS print server with AirPrint/IPP sharing and Brother HL-4150CDN driver support
### Modified Capabilities
None
## Impact
- New Containerfile (and possibly supporting files) in repository root
- Uses Brother driver artifacts in `assets/Brother HL-4150CDN/`
- Runtime ports: CUPS (631), mDNS (5353/udp) for AirPrint
- Depends on Avahi/DBus, CUPS, and 32-bit compatibility libs for Brother binaries
@@ -0,0 +1,81 @@
# Spec Delta
## Purpose
Provide a containerized CUPS print server that shares the Brother HL-4150CDN network printer as an AirPrint and IPP printer so clients can print without installing local printer drivers.
## ADDED Requirements
### Requirement: Container image builds with required dependencies
The container SHALL include CUPS, Avahi/mDNS, DBus, and required 32-bit runtime libraries to run Brother HL-4150CDN i386 binaries.
#### Scenario: Image contains CUPS
- **WHEN** the image is built
- **THEN** CUPS is installed and available at /usr/sbin/cupsd
#### Scenario: Image supports 32-bit Brother binaries
- **WHEN** the image is built
- **THEN** required 32-bit libraries are present for the Brother i386 filters
### Requirement: Brother HL-4150CDN driver is installed in container
The container SHALL install the Brother HL-4150CDN CUPS wrapper, PPD, LPR/filter components from the provided driver artifacts.
#### Scenario: Driver files present
- **WHEN** the container image is built
- **THEN** the HL-4150CDN PPD and Brother filters are installed in standard system locations
#### Scenario: CUPS recognizes HL-4150CDN
- **WHEN** CUPS starts with the driver installed
- **THEN** CUPS is able to use the HL-4150CDN PPD
### Requirement: Printer is shared and discoverable
The system SHALL share the Brother HL-4150CDN printer over IPP and make it discoverable via AirPrint (mDNS/DNS-SD) on the container network.
#### 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 so macOS/iOS clients can discover it without driver installation
### 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: No client drivers required
The shared printer SHALL be exposed in a way that client devices can print without installing vendor printer drivers.
#### Scenario: AirPrint compatibility
- **WHEN** a client discovers the printer via AirPrint
- **THEN** the client uses native IPP/AirPrint drivers
### 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_IP` set
- **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_IP` and `PRINTER_PROTOCOL`
- **THEN** the device URI uses that protocol (lpd, socket or ipp)
#### Scenario: Full URI override
- **WHEN** `PRINTER_URI` is set
- **THEN** it is used as the device URI and `PRINTER_IP` is 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
@@ -0,0 +1,23 @@
# Tasks
## 1. Repository initialization
- [x] 1.1 Initialize jujutsu repository with `jj git init` in repo root and verify `.jj` directory exists
## 2. Container build setup
- [x] 2.1 Create Containerfile in repository root based on Debian/Ubuntu base image with multiarch support for i386
- [x] 2.2 Install required system packages: cups, avahi-daemon, dbus, wget/curl, and 32-bit runtime libraries (libc6:i386, libstdc++6:i386, etc.)
- [x] 2.3 Copy the local Brother driver packages (`assets/Brother HL-4150CDN/lpr-driver/hl4150cdnlpr-1.1.1-5.i386.deb` and `assets/Brother HL-4150CDN/cupswrapper/hl4150cdncupswrapper-1.1.1-5.i386.deb`) into the build context and install them in the container with `dpkg -i --force-all` (verify install reports success)
- [x] 2.4 Configure CUPS and Brother drivers (symlink PPD/filter files as needed, set up cupsd.conf for container use) and verify files are in correct locations
- [x] 2.5 Set up startup script to run dbus, avahi-daemon, and cupsd in the container
- [x] 2.6 Expose ports 631 (CUPS/IPP) and 5353/udp (mDNS) in Containerfile and verify ports are declared
## 3. Printer configuration
- [x] 3.1 Add logic/config to create and share the Brother HL-4150CDN printer (using lpadmin) with appropriate network URI and PPD; ensure printer is shared for network clients
- [x] 3.2 Configure Avahi/CUPS for AirPrint advertisement and verify printer will be discoverable
- [x] 3.3 Add environment-based configuration for the printer address and advertised name (`PRINTER_IP`, `PRINTER_PROTOCOL`, `PRINTER_NAME`, `PRINTER_DESCRIPTION`; `PRINTER_URI` overrides)
## 4. Documentation and testing
- [x] 4.1 Create or update README with instructions for building and running the container with podman (including host network mode note for mDNS, volume mounts if needed)
- [x] 4.2 Test container build with podman build and verify image builds successfully
- [x] 4.3 Test container run and verify CUPS is accessible and printer is shared/discoverable (manual verification)
- [x] 4.4 Verify `podman run` with `PRINTER_IP` and a custom `PRINTER_NAME` creates the queue at the derived URI and advertises that name
View File
Whitespace-only changes.
+32
View File
@@ -0,0 +1,32 @@
schema: spec-driven
# Project context (optional)
# Add only constraints that should guide OpenSpec artifacts and workflows.
# Include constraints an agent cannot infer by reading the code.
# Keep general project documentation and discoverable codebase facts out.
# Example:
# context: |
# Designs and tasks must cover Windows, macOS, and Linux
# Write all artifacts in Spanish
# Per-artifact rules (optional)
# Add custom rules for specific artifacts.
# Example:
# rules:
# proposal:
# - Keep proposals under 500 words
# - Always state what is out of scope
# tasks:
# - Break tasks into chunks of max 2 hours
# Per-operation guidance (optional)
# Add advisory guidance for how apply and archive work should be conducted.
# This is separate from artifact rules above.
# Example:
# operations:
# apply:
# guidance:
# - Keep test summaries concise
# archive:
# guidance:
# - Summarize the archive outcome before finishing
View File
Whitespace-only changes.