Deployment
Images
PDF Server ships as an Alpine-based image (using tini as PID 1) with a browser installed. Two families are published:
| Image | Browser | BROWSER_COMMAND |
|---|---|---|
…:latest-chromium | Chromium | chromium-browser |
…:latest-firefox | Firefox | firefox |
Multi-arch (amd64 + arm64) images are built via Earthly. You layer your templates on top — see Build your image.
Browser choice
- Chromium is the default and most-tested. It supports both factory modes.
- Firefox ships different
BROWSER_ARGSand must use--factory-type=runner.
Factory modes
--factory-type controls how browsers back the pool:
| Mode | Behavior | Notes |
|---|---|---|
runner (default) | One browser process per pooled object. | Robust isolation; works on Chromium and Firefox. |
page | One browser process; each pooled object is a tab. | Lower per-render overhead; Chromium only. |
Process model
The runner mode launches each browser in its own process group and, on teardown, escalates from SIGTERM to SIGKILL across the whole group to reap Chromium helper processes (GPU, renderers, crash handler). This prevents zombie processes accumulating. The wait before escalation is --browser-process-group-wait-timeout (default 10s).
Running as non-root
The image runs as a non-root user. Combined with the browser sandbox caveat (see Security model), run the container with a restrictive seccomp profile and, ideally, user-namespace isolation.
Configuration
Everything is set via flags or environment variables — see the CLI & configuration reference. Common production settings:
-e RENDER_POOL_MAX_TOTAL=4 # concurrency (browsers + render workers)
-e RENDER_TIMEOUT=30s
-e FACTORY_TYPE=runner
-e LOG_FORMAT=jsonSee Tuning for sizing guidance and Observability for tracing/logging.