The container image I use to build my Vietnamese translations of Beej's
Guides. One image, shared by every translation repo, so I don't have to
reinstall texlive-full from scratch every time CI runs.
Image: ghcr.io/tamnd/beej-vi-docker:latest
Debian 13 (trixie) slim, with:
pandoctexlive-full, so the bgbspd build system can findsoul,regexpatch,tcolorbox,xparse,libertinus-fonts, and whatever else the LaTeX template wants without me chasing packagesxelatexwith Libertinus Serif, Liberation, DejaVu, Linux Libertine, and Latin Modernpython3for the bgbspd preprocessorimagemagickwith the PDF security policy loosened, otherwise EPUB rasterization of the figure PDFs just silently produces blank pageslibrsvg2-binmake,zip,ncurses-bin(fortput),fontconfig,ca-certificates
It's linux/amd64 only. TeX Live on arm64 is a whole separate
adventure and none of the CI runners need it.
Every Beej translation repo I have (bgnet-vi, bgc-vi, more
eventually) runs the same build: pandoc plus xelatex plus a pile of
LaTeX packages. Before this image, each repo installed texlive-full
from scratch in CI. That's about 5 GB and roughly 13 minutes of
cold-cache install, per repo, because GitHub Actions caches are
scoped per-repository and can't be shared.
Now the install happens once, here, and every guide just pulls the image. Cold pull is about 30 seconds. Warm is a layer cache hit.
- name: Build guide
run: |
docker pull ghcr.io/tamnd/beej-vi-docker:latest
docker run --rm \
-v "$PWD:/guide" \
-w /guide \
-e BGBS_THREADS=4 \
ghcr.io/tamnd/beej-vi-docker:latest \
bash scripts/build_vi.shThe package is public, so no docker login step. No buildx either.
docker pull ghcr.io/tamnd/beej-vi-docker:latest
docker run --rm -v "$PWD:/guide" -w /guide \
ghcr.io/tamnd/beej-vi-docker:latest \
bash scripts/build_vi.shPodman works the same. Swap docker for podman.
The image expects your guide repo mounted at /guide, and a
scripts/build_vi.sh (or whatever you call yours) to drive the
make / pandoc / xelatex pipeline.
| Tag | What it is |
|---|---|
latest |
Tip of main. Rebuilt when the Dockerfile changes, and on the 1st of each month so OS patches get picked up. |
YYYY-MM-DD |
A dated snapshot built the same day as latest. Pin to one of these if you want reproducible builds. |
sha-<shortsha> |
Built from a specific commit of this repo. |
For guide builds I just roll with latest. If I ever need a
deterministic rebuild of an old release, I'll go grab the right
dated tag.
Mostly I don't have to.
- Edit
Dockerfile, push, the workflow builds and publishes. - No code change, just want fresh OS packages? The monthly cron handles it. Or hit Run workflow on the Actions page.
- On PRs the workflow builds the image and runs a small smoke test (pandoc, xelatex, python3, imagemagick, rsvg, Libertinus fonts) but doesn't push. The smoke test is the whole contract: if that passes, it's good enough to build the guides.
tamnd/bgnet-vi: Beej's Guide to Network Programming, Vietnamese translation.tamnd/bgc-vi: Beej's Guide to C Programming, Vietnamese translation.
Dockerfile and workflows in this repo are MIT. The published image bundles Debian packages under their own licenses, so if you plan to redistribute the image itself, go read those.