Skip to content

Dockerfile and Runtime Architecture Specification

1. Scope and Intent

This document is the normative specification of the container image produced by this repository Dockerfile.

Image purpose: - Provide a CUPS-based printing runtime for abcdesktop. - Bundle and run two Node.js services used by the printing workflow. - Run all runtime processes under supervisor.

Design style: - Single-stage image. - Runtime is process-supervised multi-service (not a one-process image). - Configuration-heavy image where repository-provided /etc content defines behavior.

2. Base Image and Global Build Inputs

2.1 Base image

  • Base image: node:20

Implications: - Node.js runtime is available for printer-service and file-service. - Debian/apt package management is available.

2.2 Build argument contract

  • ARG BRANCH=4.4
  • ENV BRANCH=$BRANCH

Meaning: - BRANCH selects which branch is cloned for external service repositories. - If BRANCH is not provided, branch 4.4 is used.

Example build:

docker build --build-arg BRANCH=4.4 -t oc.cupsd:4.4 .

3. External Source Dependencies (Build-Time)

The Dockerfile clones source code at build time from:

  • https://github.com/abcdesktopio/file-service.git into /composer/node/file-service
  • https://github.com/abcdesktopio/printer-service.git into /composer/node/printer-service

Branch selection: - Both repositories are cloned with -b $BRANCH.

Reproducibility note: - Because clones are branch-based (not commit-pinned), resulting images can vary over time for the same Dockerfile and BRANCH value.

4. Dependency Installation Behavior

4.1 Node dependencies

For each cloned Node service: - Working directory is set to service directory. - npm install --save-prod is executed.

Behavioral implications: - Production dependencies are installed. - Exact dependency graph may change over time unless lockfiles in cloned repos are stable and honored.

4.2 System dependencies

The image installs two groups of apt packages.

Font and rendering group: - fonts-recommended - xfonts-base - xfonts-encodings - xfonts-utils - xfonts-100dpi - xfonts-75dpi - libfontconfig - libfreetype6 - fonts-freefont-ttf - fonts-croscore - fonts-dejavu-core - fonts-horai-umefont - fonts-noto - fonts-opendyslexic - fonts-roboto - fonts-roboto-hinted - fonts-sil-mondulkiri - fonts-unfonts-core - fonts-wqy-microhei

Printing and supervision group: - supervisor - smbclient - cups-pdf - cups

Cleanup behavior: - apt cache is cleaned after install. - /var/lib/apt/lists is removed to reduce layer size.

5. Files Injected from Repository

5.1 Entrypoint

  • docker-entrypoint.sh is copied to /docker-entrypoint.sh

5.2 Configuration tree override

  • Entire local etc directory is copied into /etc in the image.

This includes at minimum: - /etc/supervisord.conf - /etc/supervisor/conf.d/.conf - /etc/cups/

Operational meaning: - Container runtime behavior is strongly defined by repository config files. - Upstream defaults from the base image may be overridden by this repository content.

6. Build-Time Filesystem and Permissions

Directories explicitly created: - /var/log/desktop - /var/run/desktop - /composer/run

Additional metadata file: - /etc/build.date (contains output of date captured at build time)

Ownership adjustments: - chown -R lp:root /etc/cups/ppd /etc/cups/printers.conf

Group membership change: - root is added to lpadmin group.

7. Runtime Entrypoint Contract

Default command:

/docker-entrypoint.sh

Entrypoint runtime sequence:

  1. Export KUBERNETES_SERVICE_HOST.
  2. Compute CONTAINER_IP_ADDR as:
  3. POD_IP when provided, otherwise
  4. output of hostname -i.
  5. Rewrite /etc/cups/cupsd.conf:
  6. replace localhost:631 with ${CONTAINER_IP_ADDR}:631.
  7. Normalize DISABLE_REMOTEIP_FILTERING:
  8. default is disabled when empty.
  9. only literal enabled is preserved.
  10. Export file-service restrictions:
  11. ACCEPTFILE=false
  12. ACCEPTLISTFILE=false
  13. ACCEPTDELETEFILE=false
  14. Start supervisor in foreground:
  15. /usr/bin/supervisord --pidfile /var/run/desktop/supervisord.pid --nodaemon --configuration /etc/supervisord.conf

Runtime side effect: - cupsd.conf is mutated at container startup, so CUPS listen address is runtime-dependent.

8. Supervisor Process Topology

Supervisor master config: - /etc/supervisord.conf

Included program configs: - /etc/supervisor/conf.d/cupsd.conf - /etc/supervisor/conf.d/printer-service.conf - /etc/supervisor/conf.d/printerfile-service.conf

8.1 Process: cupsd

  • Command: /usr/sbin/cupsd -c /etc/cups/cupsd.conf -f
  • User: root
  • Autostart: true
  • Autorestart: true
  • Start priority: 10

8.2 Process: printer-service

  • Command: node /composer/node/printer-service/printer-service.js
  • User: nobody
  • Autostart: true
  • Autorestart: true
  • Start priority: 90
  • Environment:
  • WATCHDIR=/var/spool/cups-pdf/ANONYMOUS
  • CONTAINER_IP_ADDR from entrypoint export
  • DISABLE_REMOTEIP_FILTERING from entrypoint export
  • BROADCAST_SERVICE_TCP_PORT=29784

8.3 Process: printerfile-service

  • Command: node /composer/node/file-service/file-service.js
  • User: nobody
  • Autostart: true
  • Autorestart: true
  • Start priority: 10
  • Environment:
  • HOME=/var/spool/cups-pdf/ANONYMOUS
  • LOGNAME=nobody
  • DISABLE_REMOTEIP_FILTERING from entrypoint export
  • CONTAINER_IP_ADDR from entrypoint export
  • FILE_SERVICE_TCP_PORT=29782

9. CUPS and CUPS-PDF Runtime Specification

9.1 cupsd listening behavior

Configured initially in /etc/cups/cupsd.conf: - Listen localhost:631 - Listen /tmp/.cups.sock

After entrypoint rewrite: - Listen :631 - Listen /tmp/.cups.sock

9.2 Access control model

From /etc/cups/cupsd.conf and /etc/cups/cups-files.conf: - SystemGroup is lpadmin. - Administrative operations require authenticated @SYSTEM users. - Root and admin locations allow local/network-permitted access according to config rules.

9.3 PDF output contract

From /etc/cups/cups-pdf.conf: - Out /var/spool/cups-pdf/ANONYMOUS - AnonDirName /var/spool/cups-pdf/ANONYMOUS - AnonUser nobody - Grp lpadmin

Service integration contract: - printer-service watches /var/spool/cups-pdf/ANONYMOUS. - printerfile-service uses same path as HOME.

10. Network Interface Specification

Dockerfile exposed ports: - 631/tcp: CUPS endpoint - 29782/tcp: printerfile-service endpoint

Not exposed by Dockerfile but used internally by service config: - 29784/tcp: printer-service broadcast service port variable

11. Environment Variable Matrix

11.1 Build-time

  • BRANCH: selects Git branch for cloned service repos.

11.2 Runtime input variables

  • POD_IP: preferred container IP source.
  • KUBERNETES_SERVICE_HOST: exported if present.
  • DISABLE_REMOTEIP_FILTERING: accepted values effectively enabled or disabled.

11.3 Runtime computed/exported variables

  • CONTAINER_IP_ADDR: computed from POD_IP or hostname -i.
  • DISABLE_REMOTEIP_FILTERING: normalized by entrypoint.
  • ACCEPTFILE=false
  • ACCEPTLISTFILE=false
  • ACCEPTDELETEFILE=false

11.4 Service-level variables via supervisor

  • WATCHDIR=/var/spool/cups-pdf/ANONYMOUS
  • BROADCAST_SERVICE_TCP_PORT=29784
  • FILE_SERVICE_TCP_PORT=29782
  • HOME=/var/spool/cups-pdf/ANONYMOUS
  • LOGNAME=nobody