You do not have to install TeX on your own machine: a Docker image packages the entire typesetting environment, so you can turn .tex into PDF with identical results anywhere. This pairs naturally with CI (continuous integration) such as GitHub Actions — every push can build the PDF automatically. This page covers the popular texlive/texlive image and how to make TeX builds automated and reproducible in CI.
Why typeset in a container
If a distribution is the “TeX environment itself” (see Distributions), a Docker image is the box that ships that environment frozen together with its OS. Inside the box are a specific version of TeX Live, the engines, the packages, and the fonts — so whether your host is Windows or macOS or a CI server, opening the same box gives you the same environment. Its biggest payoff is avoiding the “works on my machine but fails on my colleague’s setup or in CI” mismatch.
Containers and desktop installs are not mutually exclusive. A common split is to write day-to-day with your editor and a local TeX (see Desktop installation) and hand only the final build, collaboration, or publishing to a container or CI. The key word is reproducibility: pin the version with a tag, and rebuilding half a year later still yields the same PDF.
The texlive/texlive image
The most widely used official image is **texlive/texlive, maintained by Island of TeX**. It is published in two places: docker.io/texlive/texlive on Docker Hub and registry.gitlab.com/islandoftex/images/texlive on GitLab. Inside is TeX Live (the current stable release as of 2026 is TeX Live 2026, released March 2026), with the engines, packages, and tools such as latexmk. It is rebuilt roughly weekly to track CTAN updates.
Tags let you pick a scheme (size tier). There are five — minimal, basic, small, medium, full — and latest maps to the largest, full (all packages). You can combine these with whether documentation and sources are included: the bare tag has neither, -doc adds docs, -src adds sources, and -doc-src adds both. Docs and sources are bulky — latest-doc-src is roughly 6.5 GB, for instance. CI rarely needs them, so a bare or smaller scheme pulls faster. There are also -context variants for ConTeXt users.
| Tag | What you get | |
|---|---|---|
latest | Latest full scheme (all packages); no docs/sources | A reasonable default |
latest-small | Small scheme; lightweight, quick to pull | When you want fast CI |
latest-medium | Medium scheme; a mid-size install | A balanced middle ground |
latest-doc-src | Full + docs + sources; ~6.5 GB | Local use where you also want texdoc |
TL2026-… | Date-pinned tag (below); for reproducibility | To freeze a production build |
Usage is simple: docker run with the current directory mounted into the container, then run latexmk inside it. Here is a one-off build of a local main.tex. --rm discards the container afterwards, -v "$PWD":/work maps your current location to /work, and -w /work makes that the working directory. The resulting PDF lands right back in your folder.
docker run --rm -v "$PWD":/work -w /work texlive/texlive latexmk -pdf main.texFor a Japanese document, run a specific engine instead of plain latexmk — e.g. latexmk -lualatex main.tex for LuaLaTeX, or latexmk main.tex for the upLaTeX + dvipdfmx route once you provide a .latexmkrc. The mount works the same way: both input and output live in your local directory.
Pin the tag for reproducibility. latest changes quietly, but Island of TeX keeps date-pinned tags of the form TL{release}-{year}-{month}-{day} (e.g. TL2022-2022-06-05). If a later image introduces a regression, you can revert to a date that worked. For production builds or a paper’s final version, it is safer to name such a fixed tag — texlive/texlive:TL2026-… — rather than latest.
Automated builds with GitHub Actions
For a GitHub repository, GitHub Actions can compile your .tex on every push. The popular choice is **xu-cheng/latex-action (v4** as of 2026). It uses a container with a full TeX Live inside and calls latexmk by default, so the workflow is just a few lines. Below is a minimal example that builds main.tex at the repo root on each push and saves the PDF as a build artifact.
name: Build LaTeX document
on: [push]
jobs:
build_latex:
runs-on: ubuntu-latest
steps:
- name: Check out the repository
uses: actions/checkout@v4
- name: Compile the document
uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
- name: Upload the PDF
uses: actions/upload-artifact@v4
with:
name: PDF
path: main.pdfOn push, a container starts on GitHub’s runner and the main.tex named in root_file is compiled by latexmk. The default latexmk arguments are -pdf -file-line-error -halt-on-error -interaction=nonstopmode — a CI-friendly setting that stops on errors and runs to the end without prompting. The finished PDF can be downloaded as an artifact from the Actions run page.
Know the main inputs (with:). root_file is the build target (globs allowed). Switch engines with latexmk_use_lualatex: true for LuaLaTeX or latexmk_use_xelatex: true for XeLaTeX (LuaLaTeX is the easier route for Japanese). texlive_version selects 2020–2026 or latest, so you can pin by year for reproducibility. os is the base operating system — the default is the lightweight alpine, with debian available when you need it. For packages that use \write18, set latexmk_shell_escape: true.
To make builds faster, you can cache things that would otherwise be re-installed or re-downloaded on every run via actions/cache. That said, latex-action already bundles a substantial TeX Live, so most projects run at a practical speed out of the box. Start with the minimal setup and optimize only once slowness actually becomes a problem.
GitLab CI takes the same approach
GitLab CI follows the same idea, only you name the image directly instead of using a dedicated action. Set the job’s image: to texlive/texlive:latest (or a date-pinned tag), run latexmk -pdf main.tex in script:, and save the PDF via artifacts:. Because it rests on the same image, you get the same typeset result as GitHub Actions.
build:
image: texlive/texlive:latest
script:
- latexmk -pdf main.tex
artifacts:
paths:
- main.pdfThe essence is the same on any service: inside a version-pinned image, let **latexmk drive a one-shot build**, and collect the resulting PDF as an artifact. That is the shared pattern for running TeX in a container or CI. The mechanics of day-to-day automated builds are explored further on the “CI” and “Automated builds” pages.