ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Docker化TeX Live:一键解决LaTeX环境配置与迁移痛点

Docker化TeX Live:一键解决LaTeX环境配置与迁移痛点 从第一次在 Windows 上装了三个小时 TeX Live结果编译论文时发现缺了一堆宏包、版本还和导师的模板不兼容到后来切到 Linux 还是被各种依赖问题折磨我一度觉得 LaTeX 这玩意儿就是劝退新人的。直到我试了 Docker 部署 TeX Live第一次体验到一条命令拉起完整编译环境、换电脑零成本迁移的时候才真正意识到原来 LaTeX 环境的正确打开方式是容器化。这篇文章我结合自己踩过的坑把整个 Docker 部署 TeX Live 的完整方案、常用配置和问题排查写出来适合正在被 LaTeX 环境折腾的论文党、想统一团队编译环境的技术负责人以及准备把 LaTeX 编译做成自动化流水线的朋友。1. 为什么非得用 Docker 来装 LaTeX 编译环境1.1 传统本地安装到底有多痛先说说我自己在本地装 TeX Live 的血泪史。第一次在 Windows 上安装ISO 镜像解压出来好几个 GB安装向导点来点去大概花了将近两小时才装完。这还算顺利的更头疼的是后面宏包版本冲突。MacTeX 和 Windows 版 TeX Live 的宏包更新时间不一样同一份模板在两个平台上编译出来的排版效果居然有细微差别页边距或间距偶尔差零点几毫米。导师模板依赖各种旧宏包。有些学校或期刊提供的模板是几年前写的默认依赖的宏包版本比较旧新装的 TeX Live 2026 一编译就报错。为了迁就模板你不得不去手动装旧版宏包然后系统又提示和现有包冲突。换电脑全重来。实验室的电脑、家里的电脑、笔记本每台都要重新下载几百 MB 的安装包装完还要再配置字体、环境变量、编辑器插件。如果你只是写个简单文档这些痛点可能不明显。但一旦写毕业论文、投期刊论文模板复杂度上去之后这些问题会被无限放大。我在写学位论文时正文加图表加附录一共三十多个文件因为本地宏包环境不一致同一份代码在不同电脑上编译出来的目录页码居然不同那种心情真的很难形容。1.2 容器化方案的核心优势Docker 把这些事全部打包掉本质上就是一句话你的编译环境就只是一个镜像一个容器花费时间从两小时变一分钟。拉完镜像直接编译不用安装向导不用配置路径。环境完全一致。容器里是什么版本就是什么版本不管你是 Windows、macOS 还是 Linux编译效果完全一样。不会污染宿主机。所有 TeX Live 相关文件都在容器里删掉容器就干干净净不用一堆卸载残留。宏包和字体可以直接塞进镜像。包括那些很难找的中文字体、期刊专属字体构建镜像时一次搞定。换电脑迁移成本接近零。一个 Dockerfile一条命令新机器上直接复现全环境。我个人觉得这项方案特别适合两类人第一类是写毕业论文的学生模板复杂、宏包依赖多而且经常需要在学校机房、宿舍、图书馆之间换设备第二类是实验室或项目组里有统一排版需求的技术团队需要确保不同成员交上来的 LaTeX 文档编译环境一致。2. 部署前你要知道的核心概念和镜像选型2.1 Docker 分层镜像与缓存机制是怎么回事很多人第一次用 Docker 部署 TeX Live 时会被“镜像”“容器”“层”这些概念搞得有点懵。我尽量用大白话解释。你可以把 Docker 镜像理解成一个压缩好的操作系统快照它里面已经预装了所有需要的东西比如 TeX Live 的二进制文件、字体、宏包。容器则是这个镜像的一个实例就像你用同一个系统镜像装了多台虚拟机每台都能独立运行。镜像里的每一层代表一个操作指令比如“执行 apt 安装某个软件包”“从官网下载某个字体文件”这些层是只读的层叠在一起构成最终镜像。构建镜像时有一个关键机制叫层缓存。如果你多次构建同一个镜像只有发生改动的层会被重新构建没改动的层直接复用缓存这样能大幅节省时间和网络流量。比如你加了一个新字体文件重新构建时只会重建添加字体之后的那几层前面对系统库和 TeX Live 的安装层全部走缓存。注意如果你用卷挂载的方式工作宿主机和容器之间的数据交换不会影响镜像层缓存。你在容器里改文件宿主机同步就能看到这是最常用也最灵活的工作模式。2.2 三个主流镜像方案怎么选用 Docker 部署 TeX Live镜像方案大致有下面几种我分别说下适用场景镜像方案优点缺点适合人群官方texlive/texlive版本全、平台多、持续更新镜像较大完整版约 4-6 GB需要全量宏包、不太在意磁盘和拉取时间的人第三方轻量镜像如基于 Alpine体积小、构建快宏包不完全缺失时需手动补只写简单文档、对体积敏感的场景自建镜像Dockerfile 安装完全定制、可控性最强需要自己维护构建时间长有固定模板和字体需求、想要环境一致性的团队/个人我自己的选择是官方镜像做底再叠加自定义层。官方镜像里的 TeX Live 比较完整常见宏包都有一般学生模板都能直接用。但有些特殊字体或者小众宏包官方镜像里没有这时候就自己在 Dockerfile 里加一层去装。这样既避免了从零构建的复杂又能把特殊依赖固化下来。2.3 版本选择和拉取加速的一些经验镜像用latest标签还是指定版本标签如果只是自己写文档无所谓用 latest 就行。但如果是团队协作或要配合论文模板长期使用强烈建议固定一个具体版本比如texlive/texlive:2025这样可以保证大家用的宏包版本是同一批。拉取镜像时官方仓库在国内经常比较慢。这时候如果公司或学校有可用的内网镜像仓库可以直接配置镜像加速地址方法是在 Docker Desktop 的设置里把 registry-mirrors 指向加速地址。如果是 Linux 服务器在/etc/docker/daemon.json里配置即可。我不具体说某个服务商的名字你自己按自己网络实际情况选一个能用的、合规的加速源就好。3. 从零开始一条龙部署 TeX Live 到 Docker3.1 宿主机安装 Docker 的三种方式机器上还没有 Docker 的话先把 Docker 装好。Windows 推荐装 Docker Desktop这是最省事的方式安装包下载完成后一路下一步就行注意安装过程中会要求启用 WSL2 或者 Hyper-V按提示重启即可。macOS 同样装 Docker Desktop安装完打开应用等右上角图标变成绿色就说明引擎已经启动。Linux 直接用系统命令装Ubuntu/Debian 下执行sudo apt update sudo apt install docker.io sudo systemctl enable --now docker装完以后用docker --version验证是否成功能看到版本号就说明 Docker 已经就绪。提示Windows 用户如果之前用过旧版 Docker Toolbox先彻底卸载干净避免和 Docker Desktop 冲突。这个坑我遇到过安装报错查了半天最后发现是两个版本抢同一个虚拟化端口。3.2 拉取并验证 TeX Live 镜像打开终端执行下面的命令拉取官方镜像docker pull texlive/texlive:latest如果你是第一次使用拉取时间可能比较长完整版镜像有 4-6 GB 左右具体看网络情况。拉取完成后用docker images看看镜像列表里是否出现texlive/texlive并且 TAG 为latest看到就说明镜像已经就位。接下来验证容器能正常运行。执行docker run --rm texlive/texlive:latest pdflatex --version这条命令的含义是启动一个基于该镜像的临时容器并执行pdflatex --version打印一下版本信息执行完之后容器自动删除--rm参数。如果能看到类似 “pdfTeX 3.141592653” 这样的版本输出说明环境已经能跑了。3.3 创建你的第一个容器化 LaTeX 项目镜像能跑pdflatex --version是基础但真正要编译你的论文肯定不能让容器里去敲命令、改文件那样太蠢了。正确做法是用volume卷挂载的方式把宿主机上的论文目录映射到容器内部的工作目录。先在宿主机上建一个工作目录比如~/latex-project然后在里面新建测试文件test.tex\documentclass{article} \begin{document} Hello, Docker \LaTeX{}! \end{document}然后运行docker run --rm -v ~/latex-project:/work -w /work texlive/texlive:latest pdflatex test.tex这里几个参数我拆开解释-v ~/latex-project:/work把宿主机的~/latex-project目录挂载到容器内的/work目录这样容器内读写的文件会和宿主机实时同步。-w /work指定容器内的当前工作目录为/work。pdflatex test.tex容器启动后自动执行的编译命令。执行完以后去~/latex-project目录看看应该能看到生成的test.pdf文件。到这里一个最基础的 Docker 化 LaTeX 编译环境已经搭好了。3.4 用 docker-compose.yml 把命令固化下来每次都敲这么长一串docker run命令确实麻烦而且容易记错参数。推荐用docker-compose.yml把配置固化下来不仅记不住命令的问题解决了团队里其他人也能直接一键启动同样的环境。在项目目录下新建docker-compose.ymlservices: latex: image: texlive/texlive:latest container_name: my-latex volumes: - ./:/work working_dir: /work tty: true stdin_open: true配置好之后在项目目录下只需要运行docker compose up -d docker compose exec latex bash第一条命令创建并启动容器第二条命令进入容器内的交互式终端。之后你可以在里面执行xelatex test.tex、makeindex、bibtex等各种编译命令就好像在本地装了一个完整的 TeX Live 环境。在容器内操作完不需要手动exit退出吗不是需要exit退出容器终端但容器本身通过docker compose stop停掉即可。数据都在挂载卷里不会丢。4. 编译中文论文的关键配置字体、引擎和宏包4.1 引擎选型用 xeCJK 还是 ctexLaTeX 编译中文文档最核心的问题就是字体和中文排版。传统的pdflatex配合 CJK 宏包也可以处理中文但用的时候比较折腾字体编码问题尤其多。我现在几乎只用xelatex配合ctex宏包这个组合对中文支持最友好ctex宏包自动处理中文排版细节比如段落缩进、中文标点压缩、章节标题格式等。xelatex引擎直接支持系统字体不需要像旧方案那样还要配置字体编码。在 Docker 环境里只要在documentclass中引用ctex宏包就能用了。示例\documentclass[UTF8]{ctexart} \begin{document} 你好Docker 与 LaTeX \end{document}然后编译命令也用xelatexdocker run --rm -v ~/latex-project:/work -w /work texlive/texlive:latest xelatex -interactionnonstopmode -synctex1 test.tex4.2 中文字体缺失问题与解决方案如果你直接拿上面这个命令编译中文文档很可能会报一堆字体找不到的错误因为官方 TeX Live 镜像里预装的中文字体很少。我自己遇到过的报错就是类似于 “The font ‘FandolSong-Regular’ cannot be found”。这种情况是因为ctex宏包默认依赖的中文字体没有齐全。解决思路有两个方向方案一在宿主机上装字体然后挂载进容器把需要的中文字体文件.ttf或.otf放到一个目录比如~/latex-project/fonts/然后在挂载时多挂一个目录docker run --rm \ -v ~/latex-project:/work \ -v ~/latex-project/fonts:/usr/share/fonts/custom \ -w /work \ texlive/texlive:latest \ xelatex -interactionnonstopmode test.tex前提是你把字体放到了容器内的字体目录然后执行fc-cache -f刷新字体缓存。字体多的情况下每次启动容器都刷新一次有点麻烦但胜在宿主机上不用装 Docker 之外的东西。方案二我个人推荐把这些字体固化到镜像里如果你长期需要编译同一套论文模板最省心的方式是在 Dockerfile 里把字体装好。下面是自定义镜像的示例DockerfileFROM texlive/texlive:latest # 安装中文字体以思源宋体、思源黑体为例 RUN apt-get update \ apt-get install -y fonts-noto-cjk fonts-noto-cjk-extra \ apt-get clean \ rm -rf /var/lib/apt/lists/* # 复制项目所需到镜像 COPY fonts/ /usr/share/fonts/custom/ RUN fc-cache -f构建自定义镜像docker build -t my-latex:2025 .之后用my-latex:2025替代默认镜像编译字体问题就不会再出现了。整个镜像构建好以后给团队其他人共享大家拉下来就能获得一致的中文排版效果。提示如果学校单位有规定不能用Noto CJK这类字体而必须用宋体、黑体等指定字体你需要向相关版权方获取合法授权后把相应字体文件拷贝到fonts/目录并重新构建镜像。版权问题务必自己把控好。4.3 编译脚本避免反复敲长命令刚才我写了很多docker run带各种参数的命令实际写论文的时候如果每次都敲一遍还是会疯掉。建议在项目下写一个简单的编译脚本compile.sh#!/bin/bash IMAGEmy-latex:2025 WORKDIR$(pwd) docker run --rm \ -v $WORKDIR:/work \ -w /work \ $IMAGE \ latexmk -xelatex -interactionnonstopmode -halt-on-error $1执行前先给脚本加执行权限chmod x compile.sh之后每次编译只需要./compile.sh main.texlatexmk是非常好用的自动化编译工具它会自动处理多次编译的依赖比如交叉引用、目录、参考文献等最终直接生成正确的 PDF。不加-halt-on-error的话编译出错也会继续跑生成的 PDF 可能不完整加上以后一旦报错马上停止方便你快速定位错误位置。5. 进阶玩法把 LaTeX 编译能力迁移到编辑器、CI 与自动化场景5.1 用 VS Code 的 LaTeX Workshop 配合容器编译之前我一直建议在容器里执行编译命令但对很多人来说这样写论文太反人类了。大家更习惯在编辑器里写完一段就顺手编译预览。其实 VS Code 配合 LaTeX Workshop 插件并且把编译方案指向容器内的命令是能达到“编辑器里一键编译”的体验的。具体做法是在 VS Code 的设置settings.json里配置 LaTeX Workshop 的编译 recipe使用容器编译。大致思路是{ latex-workshop.latex.recipes: [ { name: docker-xelatex, tools: [docker-xelatex] } ], latex-workshop.latex.tools: [ { name: docker-xelatex, command: docker, args: [ run, --rm, -v, %DIR%:/work, -w, /work, my-latex:2025, xelatex, -interactionnonstopmode, -synctex1, %DOC% ] } ] }其中%DIR%是 LaTeX Workshop 提供的变量代表当前打开的.tex文件所在的目录%DOC%是当前文件名。这样你按Ctrl Alt B就能直接在容器里编译当前文档预览效果和在本地装 TeX Live 完全一致。实际使用中有一个小坑LaTeX Workshop 默认根据自带的latexmk工具在本地找编译器不会自动知道你要用 docker。你要在 recipe 中把工具名改成自己配置的docker-xelatex并且latex-workshop.latex.recipe.default也改成对应 recipe 的名称不然它还是会优先调用本地的 pdflatex 导致报错。5.2 用 GitHub Actions 或 GitLab CI 做自动编译Docker 化 LaTeX 在自动化方面更夸张的优势体现在 CI持续集成里。我现在习惯的做法是论文全部存在 Git 仓库里每次 push 到远程分支后CI 自动用 Docker 镜像编译 PDF然后把生成的 PDF 作为构建产物保存下来。这样团队审阅时根本不需要本地装 LaTeX直接下载产物就能看。以 GitHub Actions 为例.github/workflows/compile.yml可以这样写name: Compile LaTeX on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Compile with Docker run: | docker run --rm -v $PWD:/work -w /work \ texlive/texlive:latest \ latexmk -xelatex -interactionnonstopmode -halt-on-error main.tex - name: Upload PDF uses: actions/upload-artifactv4 with: name: compiled-pdf path: main.pdf如果用的是 GitLab CI.gitlab-ci.yml里同样能定义image: texlive/texlive:latest然后直接执行编译命令。真正好的体验在于不需要在 CI runner 上预先安装任何 TeX Live 相关的东西runner 只需要有 Docker 环境即可。5.3 定制化容器作为团队共享编译环境如果你在实验室或公司里带项目经常碰到新成员加入后环境不一致的问题这种“共享编译环境”的模式更推荐。做法非常简单把Dockerfile、字体目录、必要的宏包目录统一放在一个latex-env仓库里。写好docker-compose.yml和一份简短的 README新成员只需 clone 仓库、安装 Docker、运行docker compose up -d。写论文直接用挂载卷的方式本机编辑、容器编译。这样至少有三个好处新成员不用研究 TeX Live 怎么安装、宏包在哪下拉起来直接用。你们用的宏包版本、字体、编译参数完全一致交叉审核文档时不会出现“我这边编译出来页码不对”的问题。即使有人把容器搞坏了删掉重建也就几秒钟的事不会影响宿主机任何东西。5.4 直接使用 TexLive 官方容器做文档协作还有一种比较轻量的使用场景我身边不少同学也在用把自己平时写的小文档、公式笔记、作业等所有 LaTeX 源码放进一个目录然后用官方镜像直接编译不折腾任何自定义配置。因为你用到的宏包很有限官方镜像完全覆盖。这种模式下Docker 的角色就是“一个不占宿主机空间的 TeX Live 运行时”随用随开用完即删。6. 实战中常见的坑与排查技巧6.1 中文文档编译出来缺少字体或乱码的排查这是出现频率最高的一个问题。报错信息通常是The font XXX cannot be found for character ...排查思路按顺序来先确认用的是xelatex引擎编译而不是默认的pdflatex。从报错信息很难看出来但有中文内容时pdflatex 经常会因为编码问题报错而且乱码很严重。再确认容器里确实有中文字体。执行这个命令看字体列表里是否有中文字体的名字docker run --rm texlive/texlive:latest fc-list :langzh如果没有字体输出就是缺少中文字体按上面第 4 节给的 Dockerfile 方案补装字体。如果字体存在仍报错检查ctex宏包是否可以正常加载。可以在文档开头用\usepackage{ctex}然后编译一个最小示例逐步排查。6.2 编译超时或命令行卡死怎么办如果编译文档较大图片多、交叉引用多容器编译时间会比较长。如果你用 VS Code 的 LaTeX Workshop 调用 docker 编译可能遇到默认超时时间不够长的报错大文档还没编译完就提示超时。解决办法是在 VS Code 设置里增加超时时间{ latex-workshop.latex.build.timeout: 300 }单位是秒按你的文档复杂度调整。我写学位论文时大概要编译 1-2 分钟设为 300 秒绰绰有余。如果是命令行里直接编译卡住大概率是有等待输入操作最常见的是xelatex编译时遇到了错误询问默认会停下来等待用户输入。解决办法是在命令中加-interactionnonstopmode让它遇到错误直接就停下来而不是等待输入。6.3 镜像磁盘占用过大怎么清理官方镜像动辄几个 GB如果长期拉取多个版本磁盘占用会非常大。可以用docker system df查看各个镜像和容器的占用然后用docker system prune -a清理不再使用的镜像。如果当前项目需要保留某个特定版本别加-a只执行docker system prune删掉悬空数据即可。删除镜像和容器docker rm $(docker ps -aq) docker rmi $(docker images -q)这两个命令会把所有容器和镜像都清理掉务必确认不是在生产环境执行。新手建议一条一条看确认后手动删除。6.4 常见错误排查速查表症状可能原因解决方向编译出来没有 PDF 文件文档有语法错误导致编译终止加-halt-on-error查看首个报错位置中文乱码使用了pdflatex而非xelatex编辑器存储编码不是 UTF-8改用 xelatex以 UTF-8 编码保存文件交叉引用显示 ??只编译了一次latexmk能自动多次编译直接docker run只执行一次只会有警告使用 latexmk 或连续执行 xelatex 两次参考文献编译报错缺少.bib文件bibtex 命令执行顺序不对用 latexmk automake 自动处理 biber/bibtexdocker: command not foundDocker 未安装或未启动先安装 Docker 后重新执行命令用docker run --rm时每次都会产生一个新的容器虽然不占空间但--rm参数没加的话编译失败后容器会残留积少成多也很占磁盘也是容易忽略的坑。可以定期执行docker container prune清理。7. 我看完整个过程后的几个实际体会将我长期用 Docker 部署 TeX Live 的经验浓缩一下。官方镜像直接用基本能覆盖 80% 的日常需求真正需要自定义的往往是中文字体和几个特殊的宏包这部分通过 Dockerfile 叠加一层即可。VS Code 编辑器联动容器编译体验上已经接近本地安装完整版 TeX Live 的感受。CI 自动编译的模式尤其在多人协作或投期刊稿件时可以明显减少“我这里能编译为什么你那里报错”的沟通成本。最终给个建议别追求一开始就搞特别复杂的大而全定制镜像先用官方镜像把论文编译跑通再逐步叠加字体、宏包直到满足你的模板要求为止。等镜像稳定后这套配置能让你未来几年都省心不少。
返回列表