最近刚把我们课题组的论文写作环境整个搬到了 Overleaf 私有化部署上折腾了大概一周多总算是把 ShareLaTeX-CE 这个社区版彻底跑顺了。说实话之前我一直是本地编辑器加各种宏包手动维护的路子每逢换电脑就是一场灾难直到切到 Overleaf 私有化部署之后才算是真正意义上把“配置环境”这件事给甩掉了。这篇东西我就完全按自己的实际操作记录来写思路、步骤、踩坑、排查全都有。如果你也受够了本地 LaTeX 环境的各种折腾或者想在团队内搭一个协作编译平台这篇应该能帮你省掉不少冤枉路。1. 为什么是 Overleaf以及社区版到底能干什么先聊一个最基础的问题为什么都要做私有化部署了还选 Overleaf现在市面上的在线 LaTeX 方案不算少但真正能做到开箱即用、协作体验成熟、编译性能和原生 LaTeX 兼容性都在线这一圈筛选下来Overleaf 是几乎每个课题组都在用的选项。Overleaf 说白了就是把你本地那一整套 LaTeX 编译环境搬到了 Web 端。本地装 TeX Live 要解决的问题——宏包缺失、版本冲突、字体路径、编译引擎切换——在 Overleaf 上统统不需要你操心它自带的 TeX Live 每年更新常用宏包全都预装好。你打开一个浏览器就能写论文、编译、出 PDF还可以多人同时在线编辑实时看到彼此的改动。这个体验对多人协作的论文项目来说价值真的非常明显。再说私有化部署。Overleaf 官方提供的是一个叫 ShareLaTeX-CE 的社区版镜像这个项目后来被 Overleaf 收购社区版就一直沿用 ShareLaTeX 的代码库。它和 Overleaf 官方商业版的差别主要在这几块社区版没有登录系统的多用户管理面板但可以通过配置实现一定的权限控制适合团队内部使用。官方版的实时协同编辑、聊天评论功能在社区版里被砍掉了但文档在线编辑、编译、输出 PDF 这些核心功能都完整保留。没有官方技术支持但开源社区的文档和 Issue 资料足够应对绝大多数问题。社区版完全没有用户数限制装一次全组都能用这也是比商业版划算太多的地方。我自己测下来的实际体感是除了没有右下角那个绿色小圆点显示谁在看同一篇文档之外日常写论文、改回复信、做 Beamer 幻灯片体验和官方版几乎没差别。那到底哪些人适合私有化部署我列出几种典型场景你可以对照看看所在单位网络环境特殊访问外网不稳定但论文写作是刚需。课题组人多多人同时用官方免费版有编译时长限制付费又没预算。论文数据、源码有保密要求不允许传到第三方服务器。想深度定制 LaTeX 环境比如内置自己课题组的模板、宏包、字体甚至改编译参数官方版不允许做这种底层改动。如果你符合上面任意一条那私有化部署 Overleaf 就是一个值得投入的方向。我自己的情况是课题组每年要产出大量论文模板经常要统一调整放在官方版上每次都得手动导入导出模板私有化之后直接在服务器上改模板所有人打开就是新版效率提升非常明显。社区版镜像名是sharelatex/sharelatexGitHub 上的仓库名也是 ShareLaTeX后来官方把文档合并到了 Overleaf 项目下。理解了这一层背景后面查资料的时候就不容易绕晕了。2. 部署前的准备工作和方案选型逻辑动手之前一定要把准备工作做扎实这一步我一开始图省事跳过了结果后面返工了不少。你得先搞清楚自己要在什么环境下部署、数据放哪里、域名怎么处理这些基础决策直接影响后续稳定性。2.1 服务器配置怎么选别一上来就上高配很多人一听到“在线编译”就觉得服务器要很猛其实 Overleaf 的架构比你想象的要轻。社区版核心是 Node.js 应用 编译队列真正吃资源的是 LaTeX 编译瞬间但只要把编译超时控制好2 核 4G 的小机器完全能跑动日常的论文编译任务。我当前跑在生产环境的机器规格是 4 核 8G 内存系统盘 60G数据盘单独挂载 200G。日常同时在线 8~10 人编译一篇带 TikZ 图的论文大约耗时 15~40 秒基本不卡。如果你的团队规模更大或者经常编译超长文档建议 8 核 16G 起步。存储方面要特别留意一点LaTeX 编译过程中的临时文件非常占空间每个编译任务都会生成一堆中间产物。如果多人同时编译磁盘空间会涨得非常快。我建议数据盘至少准备 100G同时定期清理历史编译产物。操作系统我选了 Ubuntu 24.04 LTS主要是图省心包管理方便Docker 支持也成熟。CentOS 也可以用但 SELinux 偶尔会对 Docker 的数据卷权限造成困扰新手劝退。如果你只是为了试水在本地虚拟机上先跑一遍也完全可以配置可以再降一档。2.2 域名和反向代理Overleaf 社区版的配置里会有几个需要填写的站点 URL这决定了生成的链接、邮件通知里的地址格式。如果你只是内网使用填 IP 也可以但后续如果要做 HTTPS、要用固定书名号链接分享文档建议还是搞一个域名。我自己的方案是内网 DNS 解析一个专用域名比如latex.internal按某高校内网环境域名自行替换然后由 Nginx 做反向代理统一走 443 端口HTTP 自动跳转 HTTPS。证书用的内部 CA 签发浏览器装好根证书后访问就没有告警了。如果你没有内部 CA直接用自签证书也行只是每次访问要多确认一次。这里有一个核心决策端口直接暴露还是走反向代理。我强烈建议走反向代理原因有三Overleaf 的 Web 服务默认监听 80 端口直接暴露的话无法低成本叠加 HTTPS。后续如果要加文件上传大小限制、请求体大小限制、WebSocket 支持Nginx 层处理更灵活。多服务共存时反向代理可以按路径分流Overleaf 的某个域名路径后面还可以再挂其他内部工具。2.3 用 Docker Compose 还是分开跑ShareLaTeX-CE 最省事的部署方式就是用 Docker。官方提供了一份docker-compose.yml模板里面涵盖了三类核心服务sharelatex主应用容器。redis用于缓存和任务队列。mongo存储文档元数据和用户信息。实际部署时我是把这三个服务放在一个 Compose 项目里的网络、数据卷都统一管理。唯一单独拎出去的是文档存储我用的是服务器本地目录直接映射进容器而不是用 Docker 命名卷后面迁移备份会容易很多。另外如果你是企业级场景用户量很大可以考虑把编译节点单独拆出来用独立的容器跑编译任务。但社区版默认架构里编译和主应用是同一个容器对于课题组这种量级完全不是问题别过度设计。2.4 环境变量清单在真正写 Compose 文件之前你得先把几个关键环境变量搞清楚。这些都是社区版运行时必须的漏一个都有可能起不来或者功能异常SHARELATEX_APP_NAME应用展示名称比如“课题组 LaTeX 协作平台”会显示在浏览器标签页和页面标题上。SHARELATEX_SITE_URL对外访问的地址必须和 Nginx 里配置的域名保持一致。SHARELATEX_MONGO_URLMongoDB 连接串。SHARELATEX_REDIS_HOSTRedis 主机名。SHARELATEX_SECRET用于加密会话数据的密钥要设置成一个足够长的随机字符串。SHARELATEX_EMBER_CLI_PATH、SHARELATEX_APP_NAME这些属于内部变量用默认值就行。SHARELATEX_LEFT_MENU_DISABLE之类的功能开关属于可选项初期可以不管。这些值看着繁琐其实逻辑很顺畅就是告诉应用“你的数据库在哪、对外地址是什么、会话加密用什么密钥”。把这一层理解了后面即使报错也能很快定位到具体原因。好准备工作到此就位下面进入实战环节。我会把完整部署流程按步骤拆开跟着做基本可以零基础跑通。3. 完整私有化部署流程实录这个章节是我从零开始部署的完整过程每一步都会讲清楚操作原因而不仅仅是丢命令出来。3.1 Docker 环境初始化服务器刚到手时是一台干净的 Ubuntu 系统。第一步先做系统更新和基础工具安装sudo apt update sudo apt upgrade -y sudo apt install -y curl git vim unzip然后安装 Docker。Ubuntu 上我建议用官方源而不是 Ubuntu 自带的老版本命令如下curl -fsSL https://get.docker.com | sudo sh sudo systemctl enable --now docker安装完成后验证一下 Docker 是否正常sudo docker run hello-world看到Hello from Docker!就说明 Docker 守护进程已经在跑了。这里顺带提一句国内服务器如果拉取 Docker Hub 镜像速度不理想可以给 Docker 配置镜像加速器。具体做法是编辑/etc/docker/daemon.json加入你选择的加速器地址然后重启 Docker。这一步在国内环境基本是必须的不然sharelatex/sharelatex这个几个 GB 的镜像能拉到你怀疑人生。3.2 创建部署目录和目录结构我习惯把整个 Overleaf 部署都放在一个独立目录下方便备份和迁移。我的目录结构是这样的/opt/latex/ ├── docker-compose.yml ├── .env ├── sharelatex_data/ # 文档、上传文件、编译产物 ├── mongo_data/ # MongoDB 数据 ├── redis_data/ # Redis 数据 └── logs/创建命令sudo mkdir -p /opt/latex/{sharelatex_data,mongo_data,redis_data,logs}数据目录权限要特别注意因为容器里的进程不是以 root 运行的宿主机目录权限过严会直接导致容器启动时报权限错误。我直接赋予 777 权限方便省事sudo chmod -R 777 /opt/latex/生产环境追求安全的话可以精细到用户组级别但内网部署 777 问题不大。这一步是很多新手的坑容器日志一直报EACCES多半就是权限问题先想想目录权限。3.3 编写 Compose 文件和配置进入部署目录创建docker-compose.yml。我当前的版本是基于社区版最新的sharelatex/sharelatex:latest稳定标签完整内容如下version: 3.8 services: sharelatex: image: sharelatex/sharelatex:latest container_name: sharelatex restart: unless-stopped depends_on: - mongo - redis ports: - 127.0.0.1:8000:80 environment: SHARELATEX_APP_NAME: 课题组 LaTeX 协作平台 SHARELATEX_SITE_URL: http://latex.example.local SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis SHARELATEX_REDIS_PORT: 6379 SHARELATEX_SECRET: 这里填一串不少于32位的随机字符串 SHARELATEX_LEFT_MENU_DISABLE: false volumes: - /opt/latex/sharelatex_data:/var/lib/sharelatex - /opt/latex/logs:/var/log/sharelatex networks: - latex-net mongo: image: mongo:6.0 container_name: sharelatex-mongo restart: unless-stopped volumes: - /opt/latex/mongo_data:/data/db networks: - latex-net redis: image: redis:6.2 container_name: sharelatex-redis restart: unless-stopped command: redis-server --appendonly yes volumes: - /opt/latex/redis_data:/data networks: - latex-net networks: latex-net: driver: bridge注意我把主应用的端口绑定在了127.0.0.1:8000也就是仅供本机 Nginx 访问不直接对外暴露。这个细节很关键等于在防火墙层面把 Overleaf 保护起来了外部流量只能通过 Nginx 进来算是纵深防御的一个基础动作。关于镜像版本latest标签跟进官方更新比较方便但如果你追求生产环境的稳定性建议锁定到具体的镜像 Tag。社区版会不定期推送更新latest可能会在未知时间点发生大版本跳动导致配置项不兼容。我初期图省事用的latest后来一次更新后遇到编译队列异常排查了很久才发现是新版改了默认行为从那之后我就固定版本了。现在这个部署环境我用的sharelatex/sharelatex:5.1.0你可以根据自己部署当天的可用 Tag 来定。3.4 启动各组件的正确姿势写好了 Compose 文件第一件事不是直接后台启动而是先验证配置文件有没有语法错误cd /opt/latex sudo docker compose config输出正常无报错后再启动服务sudo docker compose up -d查看容器启动状态和日志sudo docker compose ps sudo docker compose logs -f sharelatex第一次启动会比较久因为容器内部要初始化 MongoDB 数据、预编译一些前端资源、初始化应用配置。我这边实测在服务器性能尚可的情况下大概需要 3~5 分钟才能看到 Web 服务真正响应。不要一看到日志在滚就急着去访问页面可以先等日志里的Listening on字样出现再打开浏览器。3.5 Nginx 反向代理与 HTTPS 配置Overleaf 容器起来了接下来配置 Nginx 反向代理。安装 Nginxsudo apt install -y nginx创建站点配置文件/etc/nginx/sites-available/overleafserver { listen 80; server_name latex.example.local; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name latex.example.local; ssl_certificate /etc/nginx/ssl/latex.crt; ssl_certificate_key /etc/nginx/ssl/latex.key; client_max_body_size 100M; location / { proxy_pass http://127.0.0.1:8000; 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; } location /socket.io/ { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这个配置里有几个点值得展开说明。client_max_body_size 100M这一项关系到你能否上传大型图片和 PDF 附件。Overleaf 默认对单个上传文件大小有限制这个限制不是 Nginx 决定的但 Nginx 层如果设得太小上传请求还没到应用就被拦下来了。默认的1m肯定不够我设到100M是为了兼容论文配图、附件这类大文件。location /socket.io/这一段是 Overleaf 实时编译日志推送和协同编辑依赖的 WebSocket 通道。不配置这个页面能打开但编译进度条会一直卡在“正在编译”或者日志不刷新而且在线编辑时多端同步会失效。这是新手最容易忽略的配置之一。启用站点并重启 Nginxsudo ln -s /etc/nginx/sites-available/overleaf /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx3.6 初始化管理员账户首次打开页面时Overleaf 会引导你创建一个管理员账号。这个账号同时也是第一个注册用户拥有系统管理权限。打开浏览器访问你的域名注册页面出来后填写邮箱和密码。这里注意社区版的用户注册默认是开放的也就是说任何人只要知道你的站点地址就能自行注册账号。如果在课题组内部使用还好如果不想对外开放注册别忘了在管理后台关闭注册功能。注册完成后登录进去左侧菜单栏可以看到Admin菜单。点击进入管理后台你会看到系统信息、用户管理、站点配置等几个面板。这里可以做的关键配置包括关闭公开注册改为仅允许管理员手动创建账号。设置默认编译时长限制。查看当前系统版本和资源使用状况。我自己是关闭了开放注册的团队人员账号由管理员统一创建省得出现校外闲散人员涌进来占用编译资源的尴尬局面。到这里overleaf 平台已经可以正常使用。接下来我会展开讲编译引擎的配置和常见问题的排查因为这些才是日常使用中真正会反复踩的坑。4. 编译引擎与全文搜索等细节配置Overleaf 社区版默认已经内置了 pdfLaTeX、XeLaTeX、LuaLaTeX 等主流编译引擎基础画质完全够用。但有几个细节默认配置下不会启用或者行为不符合预期需要你手动调整。4.1 引擎选择和中文支持配置如果你写中文论文最重要的一步是在项目设置里选择XeLaTeX作为编译引擎并且使用ctex宏包。在 Overleaf 网页的左上角点击Menu然后找到Compiler选项切换成XeLaTeX保存。从此所有项目都会默认用这个引擎编译。社区版的 TeX Live 是完整版ctex 宏包已经在里面了不需要额外安装。这一点比本地环境强行装各种中文宏包舒服太多。另外还有一个很有用的预置Overleaf 社区版支持在项目内放置一个.latexmain文件文件内容写上主.tex文件名。如果你的主文件不叫main.tex而是叫paper.tex在项目根目录新建一个paper.tex.latexmain文件里面写上paper.tex系统就会自动把它识别为主文件。多人协作时这特别有用不然每个人打开项目后都要手动设一遍主文件。4.2 全文搜索功能社区版默认是支持全文搜索的但它的实现依赖 MongoDB 的文本索引。如果你部署后发现在项目内搜不到内容大概率是索引没有构建成功。全量构建索引的命令是进入容器操作sudo docker exec -it sharelatex /bin/bash cd /var/lib/sharelatex node modules/backend/bin/search-index这个命令会根据所有项目文档重新生成文本索引。项目多的时候会比较耗时但只需要跑一次。构建完成后搜索关键词就能快速命中标题和正文内容。4.3 模板管理私有化部署的最大便利之一就是可以自己管理模板库。Overleaf 社区版的模板目录在容器内的/var/lib/sharelatex/data/templates路径。你可以把课题组统一模板打包上传到服务器上放在这个模板目录里组内成员新建项目时就能直接看到自定义模板不用每次手动导入 zip。我的做法是维护了一个私有模板仓库每次模板有更新就在服务器上替换对应的模板文件夹然后重启容器。所有人下次新建项目时拿到的就是最新版这个对课题组的规范统一帮助非常大。以前用官方版的时候每次都得让人重新上传 zip总有人用旧模板非常恼火。5. 升级、备份与安全加固的实践经验一个部署好的环境只是起点真正考验人的是后面的日常运维。我把自己在升级、备份和安全方面踩过的坑和现在的标准操作流程写出来你可以直接拿去参考。5.1 版本升级的正确姿势社区版镜像更新节奏不算快但每年总会有几个版本推进。升级前务必要先备份这是铁律。我是靠手动切镜像标签来升级的流程是这样的先停止容器sudo docker compose down。备份数据和配置直接打包映射目录。修改docker-compose.yml中的镜像标签。拉取新镜像sudo docker compose pull sharelatex。重新启动sudo docker compose up -d。启动后立刻验证用户登录、项目管理、编译出 PDF 全流程是否正常。升级中遇到的常见问题是新旧版本对 MongoDB 版本的要求不同。老版本对 MongoDB 的兼容性较好新版本可能强制要求更高的 MongoDB 版本。如果你的 Compose 文件里 MongoDB 还是老版本启动时会报连接错误这时候需要同步升级 MongoDB 容器。升级前你看看官方 Release Note 里对依赖组件的版本要求能省下不少排查时间。5.2 备份备什么、怎么备Overleaf 的数据构成并不复杂备份只需要覆盖三块MongoDB 数据这是文档元数据、用户信息、项目权限的核心。文件目录/opt/latex/sharelatex_data这是真正的.tex源码和编译产物。环境配置文件主要是docker-compose.yml和.env。MongoDB 我是在宿主机上定时通过docker exec执行mongodump命令直接导出到备份目录。文件目录和配置则直接打包。具体脚本可以写成一个简单的 cron 任务每天凌晨执行一次。恢复流程同样简单重装 Docker 环境把备份的目录原样放回去启动 Compose 后执行一次mongorestore数据和文件就都回来了。我自己实测过一整套从零恢复的流程大概 20 分钟内搞定这样心里才真正踏实。5.3 安全加固的几个实操内网部署不等于可以裸奔。说几个我觉得性价比最高的安全动作。第一关闭注册并启用管理员审核。上面提过在管理后台可以直接设为仅管理员手动添加用户。这能确保系统里只有你知道的人能用。第二给 MongoDB 和 Redis 设置密码。如果你认真看我的 Compose 文件会发现 MongoDB 和 Redis 都在内网网络里没有对外映射端口。但在容器内部主应用和数据库之间目前是明文连接的。生产环境建议开启 MongoDB 的身份认证并在 Compose 里通过环境变量传递账号密码。虽然社区版配置起来稍显繁琐但这一步值得做。第三Nginx 层做访问控制。如果你的服务器除了 Overleaf 还跑了别的服务注意在 Nginx 层区分开来。我这边是配合防火墙只放行了80/443其他端口全部拒绝外部访问。第四资源限制。在 Compose 文件里可以给容器加mem_limit和cpus避免某个用户的大量编译任务把服务器资源吃满。我用的是sharelatex: mem_limit: 4g cpus: 4这个限制下哪怕多人同时投递大型编译任务系统整体也还有余量不至于把服务器搞宕机。6. 高频问题排查速查表日常使用中遇到问题最多的几类我直接整理成速查表格方便你遇到问题时对号入座。现象可能原因排查与解决页面能打开但编译一直转圈Nginx 未配置 WebSocket 转发检查/socket.io/的 proxy 配置和proxy_set_header Upgrade是否缺失编译报告latex命令未找到TeX Live 环境未初始化完全首次启动等容器日志出现Listening on然后重试编译仍然失败则清理容器重建上传大文件到一半报错client_max_body_size设置过小调整 Nginx 层限制并检查主应用是否有独立上传大小限制中文显示为方块编译引擎选了 pdfLaTeX切换为 XeLaTeX并引入ctex宏包搜索不到任何文档内容全文索引未构建进入容器执行node modules/backend/bin/search-index全量构建索引管理员登录后看不到 Admin 菜单第一个用户注册时未勾选管理员选项确认第一个注册用户即为系统管理员后续注册用户默认不是管理员容器启动后自动退出数据目录权限不足宿主机映射目录权限设置太严改为777或调整容器运行用户访问页面时 502 Bad Gateway后端服务还没起来或容器崩溃查看docker compose logs sharelatex按日志提示定位问题这个表格只是最常遇到的几类。LaTeX 生态本身的问题也经常会混进来比如某宏包版本更新导致编译失败这种时候建议先看编译日志中具体的报错内容是哪个宏包哪一行再针对性地在项目里加\RequirePackage{fix-cm}之类的修补。另外再说一个很多新手会忽略的问题Overleaf 编译日志里显示的错误信息往往不全有时候真正的错误在日志前面几行你只盯着最后几行看会绕半天。我实践中的习惯是编译失败时先按CtrlF搜索Error或者!锁定所有出错的位置再逐个检查对应的.tex代码段。这样定位问题的效率会高很多。7. 工作流改变与进阶玩法展望整套 Overleaf 私有化部署跑通之后我们课题组的写论文流程有了很大的变化。以前是各写各的最后主笔人收集所有 fragment 再统一排版遇到格式冲突来回改好几轮。现在所有人的 LaTeX 源码都集中在 Overleaf 项目里共同编辑、当时就能看到别人的改动排版格式统一用课题组模板编译出来返工明显少了。还有一个我很推荐的用法是配合 Git 同步。Overleaf 支持通过 Git 远程操作项目这就意味着你可以本地用 VSCode 写代码、做版本管理写完后 push 到 Overleaf用它来编译 PDF。社区版的 Git 集成是完整支持的在项目菜单里找到 Git 链接复制后本地加为 remote 就能用了。对于课题组来说这个模式可以做到论文源码在 GitHub 私有仓库管理Overleaf 上只保留编译版本两者通过 Git 同步。这样既有了代码级别的版本控制又享受了 Overleaf 的编译和在线预览能力。我实测过整个流程非常顺滑。建议你部署完成后可以再花一点时间研究社区版的账号体系。它默认支持邮箱密码注册也预留了 LDAP 集成的能力虽然配置文档不如商业版详细但对高校课题组来说如果你们有统一身份认证接入 LDAP 能让成员直接用校园账号登录省掉一堆账号管理的琐碎事。我在实际使用中最满意的一点是编译环境永远是统一的再也不会出现“我电脑上能编译到你电脑上就不行”的尴尬。所有宏包版本、字体配置、编译参数全部由服务器统一控制组里任何一个人打开项目编译结果一致。对一个多人协同的课题组来说这才是 Overleaf 私有化部署真正的价值所在。如果你也准备搭一套不要急着一口气把所有功能都配齐先把平台跑起来让课题组的人开始用再根据实际问题逐步迭代。我上面写的这些内容就是你从零开始到稳定运行的最短路径了。祝你这套部署一把过早日告别坑爹的 LaTeX 配置地狱。