Skip to content

Run Prelum with Docker

The container includes Prelum, the pinned Typst compiler and the default report fonts. You need to provide an API token and publish port 9870:

docker build -t prelum:latest .
docker run --rm -p 9870:9870 \
  --memory 2g \
  -e PRELUM_API_TOKEN=replace-with-a-secret \
  prelum:latest

--memory is the whole container's budget, and it has to cover every render in flight at once. The image bounds each Typst process to 512 MiB (PRELUM_MAX_RENDER_MEMORY_BYTES) and allows two at a time (PRELUM_MAX_CONCURRENT_RENDERS), which with the request and output buffers this service holds comes to roughly 1.2 GiB of ceiling — so 2g leaves room for the interpreter itself. Give the container less and the host's OOM killer fires before any render reaches its own limit, and it need not pick the render that caused the pressure. Raise both together, or neither; see Configuration for the arithmetic.

Check that the service is running:

curl --silent --show-error http://localhost:9870/health

The response is {"status":"ok"}. You can now follow the render request guide.

Add shared fonts and packages

Mount shared resources read-only and point Prelum at their container paths:

docker run --rm -p 9870:9870 \
  -e PRELUM_API_TOKEN=replace-with-a-secret \
  -e PRELUM_FONT_PATH=/opt/prelum/fonts \
  -e PRELUM_LOCAL_PACKAGE_PATH=/opt/prelum/packages \
  -v "$PWD/fonts:/opt/prelum/fonts:ro" \
  -v "$PWD/packages:/opt/prelum/packages:ro" \
  prelum:latest

The image runs as uid 10001. Font and package mounts need only be readable by that user. A mounted PRELUM_DEBUG_OUTPUT_DIR, if enabled, must also be writable by uid 10001. See Fonts and local packages for the expected layouts.

Use a published release

Published images use ghcr.io/vrtfinland/prelum:VERSION. Pin a production deployment to the immutable digest reported with its release rather than relying on a mutable tag:

docker pull ghcr.io/vrtfinland/prelum@sha256:YOUR_DIGEST

The Dockerfile copies Typst from an official version- and digest-pinned image. Each Prelum platform image contains an SPDX SBOM and detailed SLSA v1 provenance generated by BuildKit. The final multi-platform manifest is signed keylessly with Cosign using the publishing GitHub Actions workflow's OIDC identity.

Verify a release by immutable digest:

cosign verify \
  --certificate-identity-regexp \
    '^https://github.com/VRTFinland/prelum/.github/workflows/build.yml@refs/heads/main$' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/vrtfinland/prelum@sha256:YOUR_DIGEST

Release process

Maintainers start releases manually from the release workflow on main. The requested stable semantic version must match pyproject.toml. The workflow creates the vX.Y.Z tag, runs the complete test and image publication workflow, and only then creates a GitHub release containing the immutable image digest.

A retry continues a partial release only while its tag still points to the same commit. An existing GitHub release is a successful no-op. Image publication and releases remain disabled while the repository is private; CI still runs the complete test job.