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/minimalwith only the runtime libraries. The build toolchain it needed (perl, gnupg, wget) is left behind, so the image is smaller andtlmgrno 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).