这次我们来看一个自托管 LaTeX 工作区项目TexLite。从项目定位来看它的关键词是两个——“轻量”和“自托管”。用过 Overleaf 的人应该理解在线写 LaTeX 的体验浏览器打开编辑器左边写源码右边预览 PDF不用在本地装 TeX 发行版。TexLite 想做的事情就是把类似的体验拆下来装到你自己的服务器上让论文、技术文档、数学公式工程都留在自己手里不经过第三方平台。这篇文章我会从部署开始讲然后依次展开功能验证、接口集成、资源占用、常见排错和最佳实践。如果你正在纠结“要不要自己搭一套 LaTeX Web 工作区”或者已经在搭但遇到了问题这篇文章可以直接收藏。先说清楚硬件门槛。LaTeX 本身不是 GPU 密集型应用编译 PDF 主要吃 CPU 和内存。TexLite 这类轻量级自托管项目的优势在于不需要一台高配机器普通的 2 核 4G 服务器就能跑起来日常写文档完全够用。真正吃资源的通常不是 Web 服务本身而是 TeX Live 编译工具链和文档编译过程中的临时文件。这篇文章的重点也不是理论而是怎么在真实环境里把服务跑起来、测通、用上。1. 核心能力速览在动手之前先给一个整体能力参考。需要说明的是由于项目处于“Show HN”阶段部分细节要以仓库 README 和实际版本为准下面表格里的内容我会标注哪些是从项目定位可以直接得到的信息哪些是需要实测确认的部分。能力项说明项目类型自托管 LaTeX 在线工作区核心定位轻量级、自托管数据掌握在自己手里主要功能在线编写 LaTeX 源码、编译 PDF、项目管理具体功能边界以项目文档为准部署方式可通过容器或本地进程部署推荐方式以 README 为准硬件要求普通 x86/ARM 服务器即可2 核 4G 内存可满足个人和小团队写作网络要求局域网可直接访问公网访问需配合反向代理和认证是否支持 API不确定需要看项目是否暴露编译接口本文会给出通用对接思路是否支持批量可以通过编译脚本或任务队列对多个.tex文件批量处理适合场景个人文档管理、团队协同写作、论文排版、教材与笔记整理不适合场景对 Overleaf 模板市场、完整审阅流程有强依赖的团队从项目标题可以确定的信息有三点自托管、轻量、面向 LaTeX 工作区。这就意味着服务跑在你自己可控的机器上而不是云端订阅服务资源占用经过刻意控制不会像完整版 Overleaf Community Edition 那样需要多个容器协同功能围绕 LaTeX 文档工作流展开不是通用的在线办公套件。2. 为什么需要自托管 LaTeX 工作区2.1 解决了什么问题本地写 LaTeX 的典型痛点是环境维护。每年系统升级、换电脑、换发行版都要重新装一遍 TeX Live、配一遍编辑器、折腾中文支持和中文字体。如果是多人协作更麻烦每个人的本地环境不一样同一份文档在不同机器上编译出来的 PDF 可能有差异。在线 LaTeX 服务解决了环境一致性问题但引入了另一个问题——数据不在自己手里。论文没写完的草稿、公司内部的技术文档、带有未公开数据的报告传到第三方平台总是有顾虑。TexLite 这类自托管工作区的价值就在这里把“云端编辑 统一编译环境”的方式搬到自己的服务器上。轻量级是这个项目比较关键的定位。自托管服务最怕重如果为了跑一个写文档的工具需要部署三个容器、吃 8G 内存、还得配 Redis那很多人直接放弃。轻量意味着你可以在旧笔记本、小主机、云服务器上快速跑起来维护成本低也更容易长期使用。2.2 适用场景与边界适合这种工作区的人我总结为三类。第一类是单人写作者学生或者科研人员需要管理多篇论文、课程报告、建模文档。这类人不需要复杂的协作系统只要能稳定编译 PDF、有项目文件管理就行了。第二类是自托管爱好者已经有了 NAS 或云服务器想减少对在线服务的依赖顺便把文档统一存到自己的存储里。第三类是小团队几个人合作写技术方案、产品文档、标书。这类场景对同时编辑的要求不太高但是对“统一编译环境、导出 PDF、查看编译日志”有明确需求。不太适合的场景也要说清楚。如果你的团队对 Overleaf 的模板库有强依赖需要一键套用各类期刊模板习惯用完整的审阅批注功能那轻量级自托管项目大概率无法完全替代。它更适合从零起步、自己管理模板的情况。另外如果你完全没有接触过 LaTeX首选还是先学语法和社区工具自托管工作区只是把环境复杂性的问题解决了并不降低写作本身的门槛。2.3 使用边界与合规提示涉及自托管服务有几个边界必须注意。第一文档内容安全。工作区如果部署在公网可访问的服务器上必须开启身份认证不要裸奔暴露在公网。第二如果用于公司或项目组要确认文档是否包含敏感信息建议仅在内网访问。第三如果用在线服务导入的模板和文档要确认模板的许可证允许自托管使用。第四不要把公网端口直接映射到工作区服务应该通过反向代理加 HTTPS 访问。3. 环境准备与前置条件3.1 服务器要求先给一套能够保证流畅体验的配置参考。这里的数字不是 TexLite 的具体要求而是基于 LaTeX 编译和 Web 服务的常见开销给出的建议值项目最低要求建议配置CPU1 核2 核以上内存2G4G 以上磁盘10G 可用空间30G 以上用于缓存 TeX Live 包和文档历史操作系统Linux x86_64Ubuntu 22.04 / Debian 12 / Windows 也可但 Linux 最佳磁盘空间要重点说明一下。TeX Live 完整安装接近 8 到 10G如果项目文档还保存编译产物并且保留多版本历史磁盘会很快增长。部署之前先规划好数据目录。3.2 软件依赖不同项目的依赖不同但自托管 LaTeX 工作区一般绕不开几样东西TeX Live 或具体 LaTeX 编译工具链这是编译 PDF 的基础。Node.js 或 Python取决于项目后端实现用于运行 Web 服务。Docker / Docker Compose如果项目提供容器化部署方式。Nginx 或 Caddy用于反向代理和 HTTPS。建议在部署前先确认几个版本信息操作系统的包管理器、是否已安装 TeX Live、是否已有 Docker 环境、服务器上 80/443 端口是否被占用。3.3 网络与端口规划如果只在内网使用服务跑起来后直接通过http://服务器IP:端口访问即可。如果要公网使用需要规划好工作区服务监听端口假设是 8080以项目实际配置为准。反向代理监听 80/443。是否配置域名和 HTTPS 证书。防火墙规则只放行必要的端口。部署前用下面的命令检查端口占用sudo ss -tlnp | grep -E :8080|:80|:443如果输出有结果说明端口已被占用需要换端口或先停掉占用进程。4. 安装部署与启动方式4.1 通用容器部署模板TexLite 如果提供 Docker 部署方式通常推荐用 Docker Compose 一步起服务。下面给一个通用模板服务名、镜像名和环境变量一定要替换成项目 README 中的实际值。services: texlite: image: your-registry/texlite:latest container_name: texlite restart: unless-stopped ports: - 8080:8080 volumes: - ./data:/data # 文档数据目录 - ./workspace:/workspace # 源码工作区按项目说明调整 environment: - TZAsia/Shanghai # 以下为占位变量请按 README 填写 # - TEXLITE_SECRETchange-me # - TEXLITE_PORT8080启动方式docker compose up -d docker compose logs -f texlite容器日志提示服务启动成功后访问http://127.0.0.1:8080验证。如果你的机器没有 Docker也可以考虑单容器运行docker run -d \ --name texlite \ -p 8080:8080 \ -v $(pwd)/data:/data \ your-registry/texlite:latest这里要提醒一句不要把镜像名直接拿来用。自托管项目经常需要自己构建镜像仓库里一般会有 Dockerfile你可以拉到源码后手动构建。4.2 本地进程部署通用流程如果项目不依赖容器或者你更习惯本地部署流程一般是# 1. 克隆代码 git clone https://github.com/your-account/texlite.git cd texlite # 2. 安装依赖命令取决于项目语言 # npm install 或 pip install -r requirements.txt # 3. 确认 TeX Live 已安装并能调用编译命令 which pdflatex which xelatex which latexmk # 4. 启动服务 # npm run start 或 python app.py启动后注意观察终端输出通常会出现监听地址和端口。如果是首次部署建议在前台启动一次确认没有报错后再切到后台。前台启动的好处是错误信息直接可见排查问题更快。4.3 反向代理配置反向代理的作用是让你通过https://tex.example.com访问服务而不是记一串端口号。下面是一段 Nginx 配置模板server { listen 80; server_name tex.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 300s; proxy_send_timeout 300s; } }配置好之后执行sudo nginx -t sudo systemctl reload nginx如果服务通过 WebSocket 做实时预览Nginx 配置里还需要加升级头proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade;5. 功能测试与效果验证部署完成只是第一步接下来要按功能逐项验证。下面是一套针对 LaTeX 工作区的测试流程建议按顺序执行。5.1 基础文档创建测试测试目的确认 Web 界面能正常创建项目、编辑文件、保存文件。操作步骤登录工作区。新建一个 LaTeX 项目命名如test-doc。新建主文件main.tex。输入最简单的 LaTeX 文档内容重点是验证编译链路通不通。\documentclass{article} \begin{document} Hello, TexLite! \end{document}预期结果文件能保存界面上能看到项目目录结构。判断标准如果保存按钮或自动保存生效刷新页面后内容仍在。如果刷新后文件消失排查存储目录挂载是否生效。5.2 PDF 编译测试这是核心功能。在main.tex中保留基础文档触发编译。预期结果编译成功后生成 PDF界面能预览或下载。常见失败原因编译引擎选择错误比如项目默认pdflatex但文档包含中文。缺少必要宏包。编译超时文档结构复杂而服务器性能不足。建议编译时把日志打开观察是否有红色报错行。日志是最有效的排查入口。5.3 中文文档和 XeLaTeX 测试LaTeX 工作区绕不开中文支持。最简单的测试是编译一个带中文的文档\documentclass{article} \usepackage{ctex} \begin{document} 这是一个中文 LaTeX 文档测试。 \end{document}如果项目支持选择编译引擎把引擎切换为xelatex。中文文档编译失败最常见的原因是未装ctex宏包或缺少中文字体。在服务器上可以这样检查kpsewhich ctex.sty fc-list :langzh | head -5如果kpsewhich没有输出说明ctex宏包没装需要安装完整的 texlive-lang-chinese。如果fc-list没有输出说明系统缺少中文字体安装字体或字体包即可。5.4 项目文件管理测试测试目的验证多文件项目是否能正常管理。在同一个项目中新建chapter1.tex在main.tex中通过\input{chapter1.tex}引入然后编译。\documentclass{article} \usepackage{ctex} \begin{document} \input{chapter1.tex} \end{document}预期结果子文件内容正常出现在生成的 PDF 中。这个测试很重要因为真实写作几乎都是多文件结构主文件引入章节、图表、参考文献。如果项目对子目录引用的符号链接处理不好会出现编译找不到文件的问题。5.5 公式和特殊文档测试LaTeX 的硬实力在数学公式。测试一个带公式的文档\documentclass{article} \usepackage{amsmath} \begin{document} \begin{equation} E mc^2 \end{equation} \end{document}然后测试带图片、表格的文档重点看是不是所有依赖的宏包都可用。轻量级自托管项目为了控制体积通常会裁剪 TeX Live 的宏包集。如果你常用某些宏包部署时确认已经在编译环境中安装。6. 接口 API 与批量任务思路6.1 提前确认是否暴露 API很多自托管 LaTeX 工作区会提供编译接口方便外部系统对接。如果你拿到 TexLite 的仓库后想确认它是否提供 HTTP API按这几个思路查查看 README 中是否有API或HTTP章节。查看项目中是否有api、routes、endpoints相关目录。启动服务后访问根路径之外的常见路径如/docs、/api/docs、/health。如果项目没有暴露 HTTP API也不影响批量编译因为你可以直接在服务器上调用 LaTeX 命令行工具。6.2 通用编译 API 调用模板如果 TexLite 暴露了编译接口请求方式大概率是以下的模式之一具体路径和参数以实际项目接口文档为准curl -X POST http://127.0.0.1:8080/api/compile \ -H Content-Type: application/json \ -d { project: test-doc, file: main.tex, engine: xelatex }返回结果可能包含编译日志和 PDF 下载地址{ success: true, pdf: /api/projects/test-doc/output/main.pdf, log: /api/projects/test-doc/log/compile.log }用 Python 调用的通用模板import requests import json url http://127.0.0.1:8080/api/compile payload { project: test-doc, file: main.tex, engine: xelatex } response requests.post(url, jsonpayload, timeout300) if response.status_code 200: data response.json() print(编译成功PDF 下载地址, data.get(pdf)) else: print(编译失败状态码, response.status_code) print(response.text)注意这里的接口路径是通用模板不是 TexLite 的实际接口。一定要查看项目文档后再对接不要直接照搬。6.3 批量编译任务设计虽然 Web 工作区本身不一定提供批量任务但你可以用命令行脚本实现批量编译。思路是定义一个项目列表逐个编译并把日志和 PDF 归档。#!/bin/bash # 批量编译脚本示例需要按实际环境调整 PROJECTS_DIR/workspace/projects OUTPUT_DIR/workspace/outputs for project in $PROJECTS_DIR/*; do name$(basename $project) echo 正在编译项目$name cd $project || continue xelatex -interactionnonstopmode -halt-on-error main.tex $OUTPUT_DIR/$name.log 21 status$? if [ $status -eq 0 ]; then echo $name 编译成功 cp main.pdf $OUTPUT_DIR/$name.pdf else echo $name 编译失败查看日志$OUTPUT_DIR/$name.log fi done在批量编译时要注意三点加日志记录方便失败后定位问题。编译命令加上-halt-on-error参数遇到错误立即停止而不是一直往下执行。失败重试要有间隔不要无间隔密集调用。6.4 与编辑器/工作流集成工作区编译能力还可以集成到现有工作流里。例如搭配 Git 钩子推送后自动编译并生成 PDF。与文件同步工具配合把编译产物同步到共享目录。通过定时任务对批量文档做定时编译。这些集成的可行性取决于 TexLite 是否提供文件系统访问接口或 CLI 工具。项目如果只是纯 Web 应用没有 CLI那就直接用命令行 LaTeX 工具做集成跳过中间层。7. 资源占用与性能观察方法7.1 观察哪些指标自托管 LaTeX 工作区的性能瓶颈不在 Web 服务而在编译过程。建议重点观察四个指标CPU、内存、磁盘、网络。CPUxelatex编译是 CPU 密集型任务编译大文档时会把单个内核跑满。观察命令top -p $(pgrep -d, -f xelatex)内存轻量级 Web 服务通常只占几十到几百 MB 内存但编译大型文档时 TeX 引擎的内存占用会明显上升。内存不足时编译会直接失败。观察命令free -h磁盘工作区会存储源码、编译产物、日志、包缓存。如果保留多次编译的历史 PDF磁盘占用会持续增加。观察命令du -sh /data /workspace 2/dev/null如果项目使用容器最直接的方式是docker stats texlite实时看 CPU、内存、网络和磁盘占用。7.2 编译性能优化LaTeX 编译慢通常不是 Web 服务的问题而是编译流程可以优化。几个常用手段使用latexmk做增量编译只重编译修改过的部分比每次都全量编译快很多。使用-file-line-error参数配合日志定位减少人为排查时间。减少每次编译保留历史产物或用定时任务定期清理临时文件。在服务器配置不高的场景下避免同时启动多个编译任务避免 CPU 争抢。把不常用的宏包和文档工程拆成独立项目避免一个项目越积越重。7.3 轻量级项目为什么会“越跑越重”很多自托管项目跑一段时间后变慢常见原因有三个。第一是日志增长。Web 服务日志、编译日志越积越多需要按天或按大小轮转。第二是文档历史版本。每次编译都保留 PDF 快照磁盘空间消耗很快建议设置保留策略只保留最新 5 到 10 个版本。第三是依赖包缓存。TeX Live 的包缓存可能占用几个 G如果磁盘紧张可以按需清理。8. 常见问题与排查方法自托管 LaTeX 工作区的问题主要集中在编译环境、端口、权限和前端连接这几类下面用表格直接给排查路径。问题现象可能原因排查方式解决方案页面打不开端口未监听或防火墙拦截ss -tlnp查端口监听curl 127.0.0.1:8080测本机访问调整服务监听地址、放行防火墙端口编译报错缺少宏包TeX Live 宏包集被裁剪kpsewhich ctex.sty检查宏包是否存在安装缺失的宏包或完整 texlive-lang-chinese中文 PDF 乱码未用 XeLaTeX 编译或缺少中文字体fc-list :langzh检查系统字体切换编译引擎到 xelatex安装中文字体编译超时文档过大或服务器性能不足观察top中编译进程是否存活增加latexmk增量编译拆分大文档PDF 预览未更新浏览器缓存或 WebSocket 断连刷新页面查看浏览器控制台日志清理缓存检查 WebSocket 代理升级头保存文件失败数据目录权限不对ls -l /data查看目录属主修改目录权限或容器内用户 UID / GID容器启动后立即退出环境变量、数据卷或启动命令错误docker logs texlite查看退出前日志按日志提示修正环境变量和挂载目录前端页面 502Nginx 代理目标配置错误curl 127.0.0.1:8080确认后端存活修改proxy_pass指向正确端口多人同时编译资源不足并发编译任务抢占 CPUtop观察多个 xelatex 进程加任务队列限制同时编译数量服务频繁重启内存不足触发 OOMdmesgtail -20 查看内核日志8.1 编译日志怎么看编译失败时先做一件事把编译日志完整看一遍。LaTeX 报错通常不会特别友好但关键信息集中在两类。第一类是 “File not found”说明缺文件或路径不对。第二类是 “Undefined control sequence”说明宏包没加载或命令拼写错误。查看日志时搜索这些关键词有助于快速定位grep -n ^! compile.log # 所有报错位置 grep -n not found compile.log grep -n Error compile.log8.2 权限问题的通用解法容器部署最常见的权限问题是页面提示无法写入文件。原因是宿主机数据目录属于某个 UID而容器内进程以另一个 UID 运行。解决方法是修改宿主机目录属主sudo chown -R 1000:1000 ./data如果不知道容器内用户 UID可以在容器里执行docker exec -it texlite id然后按输出的 UID 调整宿主机目录权限。8.3 中文字体问题的完整方案在 Linux 服务器上部署 LaTeX 工作区中文字体基本必踩。参考下面这套流程# 1. 安装中文相关宏包 sudo apt install -y texlive-lang-chinese # 2. 安装中文字体 sudo apt install -y fonts-noto-cjk # 3. 刷新字体缓存 fc-cache -fv # 4. 验证字体 fc-list :langzh | head -5如果装完字体后依然乱码优先排查编译引擎。pdflatex对中文支持较差统一改用xelatex编译中文文档。8.4 端口冲突问题服务无法启动先查端口sudo ss -tlnp | grep 8080如果被占用两种处理方式。第一种是换端口修改服务配置。第二种是杀掉占用进程但前提是你确认这个进程没用。杀掉进程要谨慎sudo kill -9 PID9. 最佳实践与使用建议9.1 第一次部署要做小规模验证不要直接迁移大量历史文档。建议先建一个测试项目只放一篇文章跑通“编辑、编译、预览、下载”四个核心步骤后再逐步迁移。这样能把环境问题隔离在最小范围不会拿着几十篇文档排查环境。9.2 数据目录与代码分离把数据目录和代码目录分开管理。容器重建时代码可以重新拉取但数据目录必须持久化。建议目录结构/opt/texlite/ ├── data/ # 文档数据 ├── backups/ # 备份文件 ├── logs/ # 服务日志 └── docker-compose.yml这样升级版本、重装系统都不会丢文档。9.3 定期备份自托管服务的最大风险就是数据丢失。备份不需要太复杂一个定时任务就够了30 2 * * * tar czf /backups/texlite-$(date \%Y\%m\%d).tar.gz /opt/texlite/data你可以在 crontab 里加入类似任务也可以直接配置备份工具。关键是两点备份数据目录定期验证备份文件可恢复。9.4 认证与访问控制自托管服务如果处于公网必须启用认证。如果项目本身不带用户系统一定要加反向代理层的认证。不要为了省事把端口直接暴露到公网。至少做三件事启用强制登录。通过 HTTPS 访问。对数据目录做服务账号隔离。9.5 批量任务的工程化建议如果你经常需要批量编译文档建议把任务流程做成可重复的脚本而不是每次手动点击界面。脚本要包含输入项目列表的配置文件。每个项目编译结束后记录状态。成功与失败分开归档。日志带时间戳。这样可以快速回溯“这一批文档哪些编译成功了哪些失败了失败原因是什么”。9.6 合规声明使用自托管 LaTeX 工作区处理文档时要确保你拥有文档内容的合法上传和存储权限。涉及公司内部文件时遵守公司保密要求。涉及他人论文、版权材料时确认复制和二次分发是否合规。涉及人脸照片、身份证件号、手机号等敏感信息时建议做脱敏处理再写入文档。自托管只是提供了网络层面的隔离并不自动意味着合规和安全。10. 总结与下一步TexLite 这类轻量级自托管 LaTeX 工作区最值得尝试的点在于用很低的资源成本把常用在线 LaTeX 写作体验搬回自己的服务器。如果你已经有了一台 Linux 服务器部署一套并不会花太多时间验证成本也很低。最先应该验证的功能有三个基础编译能不能跑通、中文文档能不能正常显示、文件保存和持久化是否正常。这三个点通过日常写作就已经可以用了。最容易踩的坑也很明确中文支持、宏包缺失、数据目录权限、公网暴露问题。建议部署时直接参考文章第 8 节完整排查一遍不要等出问题再回来查。后续可以继续扩展的方向包括接入 Git 做版本管理、配置 Webhook 实现提交后自动编译、对接文件同步工具、增加文档模板库。先把基础工作区用起来再按实际需求逐步加功能。部署时记得保留项目仓库链接和配置文件的备份。如果遇到环境相关的特殊问题优先在项目 Issues 里搜索——很多坑别人已经在前面踩过了。