Skip to content

The runtime image

In core the runtime image is built from source in your project, so the whole toolchain — Pandoc, TeX Live, the fonts — is yours to read and change. make image builds it; make publish runs your book against it. In core-slim the same image arrives prebuilt and signed; there, this page is background.

How it's assembled

The image starts from pandoc/minimal — the Pandoc binary and a small Ubuntu base, with no TeX Live. Keystone then installs its own TeX Live: a pinned install-tl lays down the infrastructure, and tlmgr adds exactly the packages Keystone's PDFs need. The package set is small, and each stage installs from a declaration in .docker/packages/tlmgr/.

The Dockerfile builds in stages so the build toolchain never reaches the finished image:

  • base — the general LaTeX / XeLaTeX packages (the engine, math, fonts support, hyperref, and the babel/hyphenation languages an author can select with lang:).
  • keystone-tex — the packages Keystone's own features pull in (callout boxes, drop caps, watermarks, page furniture, and so on).
  • fonts — installs the font packages and extracts only the files Keystone embeds, with each family's license alongside.
  • the final image copies the finished TeX Live tree and fonts onto a clean pandoc/minimal with only the runtime libraries. The build toolchain it needed (perl, gnupg, wget) is left behind, so the image is smaller and tlmgr no longer runs in it.

Attribution

The image carries its own NOTICE.md under /usr/share/doc/keystone/, naming what it bundles and where each license text sits inside it. Redistributing the image carries that attribution with it, independent of any project — which is what the copy in your own project covers.

Adding a LaTeX package

When a custom handler's macros.tex needs a LaTeX package the image doesn't ship, add a row to .docker/packages/tlmgr/keystone-tex.packages — the package name, and an optional description after it — then rebuild:

make image      # reinstall TeX Live with the new package
make publish    # build your book against it

The image redistributes the package under its own license, so it needs an entry in NOTICE.md.

A name that isn't a real package fails the build with package <name> not present in repository, so a typo surfaces immediately.

Reproducibility

TeX Live is installed from a frozen daily snapshot, pinned by the TL_SNAPSHOT value in the Dockerfile, so the same source rebuilds the same package versions over time. The handful of system packages underneath it still install from Ubuntu's current archive. This is the build half of the reproducibility the sandbox gives the run.

A snapshot can serve an incomplete set, and tlmgr reports success when it does. The build stops instead, naming the packages that did not arrive: retry once the snapshot is whole, or move TL_SNAPSHOT to a date that carries them.

The install-tl download is verified against a vendored TeX Live signing key (.docker/texlive-pubkey.asc). If you advance TL_SNAPSHOT to a much newer date and make image reports a signature failure, the upstream key has rotated — run make refresh-texlive-key to re-vendor it, then rebuild.

The packages are verified against that same key, and tlmgr reports the check without acting on it. The build stops instead: a snapshot whose keyring tlmgr cannot use is another reason to move TL_SNAPSHOT to a newer date.

Languages

The image bundles the standard European babel/hyphenation languages, so lang: selects any of them with hyphenation. Cyrillic text (Ukrainian, Russian) renders as long as the book uses a font that covers it — the built-in DejaVu and Linux Libertine families do (see Typography & fonts). Those languages aren't in the bundled set, so they typeset without language-specific hyphenation; adding it is a deeper change (the pattern packages must load in the base stage before the format is built).