Docker / CI 设置

您不必在自己的机器上安装 TeX:Docker 映像封装了整个排版环境,因此您可以在任何地方使用相同的过程将 .tex 转换为 PDF。这自然与 CI(持续集成)(例如 GitHub Actions)配对 - 每次推送都可以自动构建 PDF 并将其保存为工件。本页面介绍了流行的 texlive/texlive 图像以及如何在 CI 中使 TeX 构建自动化且可重现。

为什么要在容器中排版

如果发行版是“TeX 环境本身”(请参阅​​发行版),则 Docker 映像就是将该环境与其 OS 一起冻结的 盒子。盒子里面有特定版本的 TeX Live、引擎、软件包和字体——所以无论你的主机是 Windows、macOS 还是 CI 服务器,打开同一个盒子会给你相同的环境。**它最大的回报是避免“在我的机器上工作,但在我同事的设置或 CI 中失败”不匹配。

容器和桌面安装并不相互排斥。常见的拆分是使用编辑器和本地 TeX(请参阅桌面安装)进行日常编写,然后将 仅最终构建、协作或发布 交给容器或 CI。关键词是可重复性:用标签固定版本,半年后重建仍然会产生相同的 PDF。

texlive/texlive 图像

TeX Live 广泛使用的图像是 texlive/texlive,在 Docker Hub (docker.io/texlive/texlive) 和 GitLab (registry.gitlab.com/islandoftex/images/texlive) 上作为 Island of TeX 图像发布。里面是TeX Live(2026年的稳定版本是TeX Live 2026),有引擎、包和latexmk等工具。每周构建跟踪 CTAN 更新。

标签可让您选择方案(尺寸层)。有五个 — minimalbasicsmallmediumfulllatest 映射到最大的 full(所有包)。您可以将这些与是否包含 documentationsources 结合起来:裸标签两者都不包含,-doc 添加文档,-src 添加源代码,-doc-src 添加两者。文档和源代码庞大; CI 很少需要它们,因此裸露或更小的方案拉得更快。还有适用于 ConTeXt 用户的 -context 变体。

标签你得到什么
latest最新完整方案(所有套餐);没有文档/来源合理的默认值
latest-small小方案;重量轻,拉动快当你想要快速时 CI
latest-medium中等方案;中等规模安装平衡的中间立场
latest-doc-src完整+文档+来源;相当大您还需要 texdoc 的本地使用
historic tag / digest历史发布标签或图像摘要冻结生产版本

用法很简单:docker run当前目录安装到容器,然后在其中运行 latexmk。这是本地 main.tex 的一次性构建。之后 --rm 丢弃容器,-v "$PWD":/work 将当前位置映射到 /work-w /work 使其成为工作目录。生成的 PDF 会立即返回到您的文件夹中。

terminal
docker run --rm -v "$PWD":/work -w /work texlive/texlive latexmk -pdf main.tex

对于日语文档,运行特定引擎而不是普通的 latexmk — 例如提供 .latexmkrc 后,latexmk -lualatex main.tex 表示 LuaLaTeX,或 latexmk main.tex 表示 upLaTeX + dvipdfmx 路线。挂载的工作方式相同:输入和输出都位于本地目录中。

冻结环境以实现可重复性。 latest 每周都会移动到新的 TeX Live 快照,因此不要将其保留为论文最终版本或发布的教材的默认值。首先选择 TeX Live 发布年份和风格,并在适当时使用历史发布标签。不过,正如 Docker Hub 所指出的,当底层 OS 镜像更新时,甚至可以重建历史镜像。如果您稍后需要完全相同的容器,请固定图像摘要以及标签,或将已知良好的图像保存在您自己的注册表中。

使用 GitHub Actions 自动构建

对于 GitHub 存储库,GitHub Actions 可以在每次推送时编译您的 .tex。流行的选择是xu-cheng/latex-action@v4。它使用一个内部有TeX Live的容器,默认调用latexmk,所以工作流程只有几行。下面是一个最小的示例,它在每次推送时在存储库根目录构建 main.tex 并将 PDF 保存为构建工件。

terminal
name: Build LaTeX document
on: [push]

jobs:
  build_latex:
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repository
        uses: actions/checkout@v6

      - name: Compile the document
        uses: xu-cheng/latex-action@v4
        with:
          root_file: main.tex

      - name: Upload the PDF
        uses: actions/upload-artifact@v6
        with:
          name: PDF
          path: main.pdf

在推送时,容器在 GitHub 的运行器上启动,并且 root_file 中命名的 main.texlatexmk 编译。默认的 latexmk 参数是 -pdf -file-line-error -halt-on-error -interaction=nonstopmode — 一种 CI 友好的设置,出现错误时停止并运行到最后而不提示。完成的 PDF 可以作为 artifact 从 Actions 运行页面下载。

了解主要输入 (with:)。 root_file 是构建目标(允许使用 glob)。使用 latexmk_use_lualatex: true 切换引擎为 LuaLaTeX,或使用 latexmk_use_xelatex: true 切换引擎为 XeLaTeX(LuaLaTeX 对于日语来说更简单)。 texlive_version 选择 20202026latest,因此您可以按年份固定以实现可重复性。 os 是基本操作系统 - 默认是轻量级 alpine,当您需要时可以使用 debian。对于使用 \write18 的软件包,设置 latexmk_shell_escape: true

为了使构建更快,您可以缓存每次运行时都会通过 actions/cache 重新安装或重新下载的内容。也就是说,latex-action 已经捆绑了大量的 TeX Live,因此大多数项目都以开箱即用的实用速度运行。从最小的设置开始,只有当缓慢确实成为问题时才进行优化。

GitLab CI 采用相同的方法

GitLab CI 遵循相同的想法,只是您直接命名图像而不是使用专用操作。将作业的 image: 设置为 texlive/texlive:latest(或日期固定标签),在 script: 中运行 latexmk -pdf main.tex,并通过 artifacts: 保存 PDF。因为它位于同一图像上,所以您会得到与 GitHub Actions 相同的排版结果。

terminal
build:
  image: texlive/texlive:latest
  script:
    - latexmk -pdf main.tex
  artifacts:
    paths:
      - main.pdf

任何服务的本质都是相同的:在 版本固定映像 中,让 latexmk 驱动一次性构建,并将生成的 PDF 作为工件收集。这是在容器或 CI 中运行 TeX 的共享模式。在“CI”和“自动构建”页面上进一步探讨了日常自动构建的机制。

准备稿件CI-准备好

在 CI 中表现良好的稿件不依赖于您的编辑器设置。 根文件引擎帮助命令输出位置记录在存储库中。对于日语工作,请将 .latexmkrc 放在 main.tex 旁边,并明确选择 upLaTeX 或 LuaLaTeX。如果您的笔记本电脑和 CI 都运行相同的 latexmk main.tex,您就可以避免最后一刻“只有我的机器构建它”的故障。

latex
# .latexmkrc: upLaTeX + dvipdfmx
$latex = "uplatex -interaction=nonstopmode -halt-on-error %O %S";
$bibtex = "upbibtex %O %B";
$dvipdf = "dvipdfmx %O -o %D %S";
$pdf_mode = 3;

提交这个.latexmkrc,Docker和GitHub Actions将在相同的规则下构建PDF。不要在每次运行期间使用 tlmgr install 临时安装软件包,而是选择已经包含项目所需内容的 TeX Live 方案或固定图像标签;构建速度更快,故障更容易追踪。