从 ShareLaTeX 时代一路折腾过来,我自己的私有化部署方案 xuhe2/sharelatex-ce 这次终于完整跟上了官方节奏,全面支持 Overleaf 6.x。这次版本跳跃是我维护这套方案以来最大的一次,不仅仅换了镜像 tag 那么简单,底层依赖、数据库索引、编译环境全都变了。过去两周我一边在几个团队的生产服务器上做迁移,一边把踩过的坑逐个记下来,终于确认整套流程可以稳定复现。
如果你正在使用 Overleaf 官方版但受限于访问速度、数据合规或者编译排队问题,又或者你已经跑着一套社区版正在犹豫要不要升 6.x,这篇文章应该能帮你省下大量试错时间。我不会照搬官方 changelog,只会把这次升级里真正影响实际使用的细节、配置项和排查思路讲明白。
1. 为什么要把 Overleaf 私有化:数据、速度和版本控制的三重问题
1.1 官方版用着顺手,但这些坎你迟早会碰到
官方 Overleaf 的协作体验确实做得很好,但把它作为团队的长期基础设施来用,大多数人很快会撞上三堵墙。
第一堵墙是数据主权。论文原稿、实验数据、审稿意见全部放在第三方平台,一旦课题组有保密要求,或者单位的信息安全规范里有明文规定,资料存储位置就是一个绕不开的风险点。很多科研院所的合规要求里写得很清楚:重要科研数据不得存储在境外在线平台上。即便项目不涉密,让导师把未发表成果传到第三方服务器,很多老师心里也是不踏实的。
第二堵墙是访问速度和编译稳定性。官方编译资源在高峰时段非常紧张,尤其是工作日下午,编译一个短文档经常要排队几十秒,甚至直接超时。对国内用户来说,官方服务的访问延迟本来就不低,偶尔还会出现页面加载失败的情况。编辑体验一旦卡顿,整个团队的工作节奏都会被拖慢。
第三堵墙是版本不可控。官方平台升级 TeX Live 或宏包不会提前通知你,今天能正常编译的文档,明天可能就因为某个宏包变更彻底报错。对于正在赶 deadline 的团队,这种来自外部环境的黑天鹅是最难受的。
1.2 私有化部署不是整套照搬,它解决的是控制权问题
很多人误以为私有化部署就是"自己搭一个一模一样的 Overleaf",其实不然。自建方案的真正价值,是拿回三个控制权:
- 数据控制权:所有项目数据、用户数据、编译中间产物都存储在自己的服务器上,备份策略自己定。
- 资源控制权:编译超时、内存限制、磁盘配额、并发编译数都可以按团队实际需求调整,而不是被平台限死。
- 工作流控制权:可以接入团队已有的统一登录、内部模板仓库、Git 服务,把 Overleaf 真正嵌进团队的研发或科研流程里。
如果你只是一个人偶尔写写小文档,官方免费版完全够用,没必要折腾部署。但 5 人以上、有长期固定模板、对数据位置有要求的团队,私有化部署带来的收益会大得多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. xuhe2/sharelatex-ce 方案的核心思路与 6.x 升级重点
2.1 这套方案到底封装了什么
xuhe2/sharelatex-ce 本质上是一套围绕 Overleaf 社区版镜像的可复现部署方案。社区版本身是开源的,Docker Hub 上的 sharelatex/sharelatex 就是它的官方镜像,但直接用这个镜像裸跑,坑非常多:默认编译超时短、中文字体缺失、MongoDB/Redis 需要自己编排、反向代理和 HTTPS 也要自己接。
我做这套方案的思路很简单:把零散的容器编排、环境变量、数据持久化、备份策略全部固化下来,让一个只懂 Docker 基础的人也能在半小时内拉起一套可用的环境。架构层面,它由这几个核心服务组成:
| 服务组件 | 实际作用 |
|---|---|
| web | Overleaf 主应用,负责页面渲染、用户认证、项目管理 |
| document-updater | 处理文档内容更新与多人编辑时的冲突合并 |
| filestore | 文件内容的持久化存储,图片、附件、二进制文件都在这里 |
| clsi | 编译隔离服务,真正执行 LaTeX 编译的沙箱 |
| realtime | WebSocket 实时协同,保证光标、修订、评论的同步 |
| tpds | 实时推送文档状态变更 |
| git-bridge | Git 仓库与 Overleaf 项目的双向同步 |
| mongo | 存储元数据、用户信息、项目关系等结构化数据 |
| redis | 缓存与会话管理 |
这些服务从 ShareLaTeX 时代一路演化到现在,配合已经非常成熟。升级到一个新的大版本,最怕的不是功能缺失,而是容器间版本兼容出问题,尤其是 Mongo 和 Node 的跨度。
2.2 Overleaf 6.x 升级后能感受到的变化
我不太喜欢罗列官方 changelog,就说几个升级落地后能明显感知的点。
第一,TeX Live 底座更新了。6.x 内置的 TeX Live 已经升到较新的版本线,这两年新增的宏包、字体、编译支持开箱即用。以前要在模板里手动规避的老宏包冲突,很多都不存在了。
第二,修订模式(Track Changes)体验大幅提升。新增的修改可以按作者、时间、操作类型筛选,接受和拒绝修订的交互更加顺畅。多人协作场景下,导师批注、学生改稿、编辑返修全流程留痕,对审稿和团队复盘帮助很大。
第三,分享链接的权限粒度更清晰。老版本里的匿名分享功能比较弱,经常要挨个添加用户邮箱。新版可以把链接权限分成"任何人可查看"和"任何人可编辑",临时拉外部协作者进来非常方便。
第四,底层依赖升级。Node 版本、MongoDB 驱动版本都有跳跃,从 5.x 直接升到 6.x 时,老项目里的部分索引可能需要重建,这也是我反复强调"先备份再迁移"的核心原因。
3. 动手升级前,先把这三件事做扎实
3.1 完整备份:文件系统和数据库一个都不能少
社区版的所有项目数据分散在 MongoDB 和文件存储里。最稳妥的备份方案是先把整个数据目录做整体快照,再单独对 MongoDB 做逻辑导出。我实际用的是两步走:
bash复制docker compose stop
tar czf /data/backup/sharelatex-backup-$(date +%F).tar.gz /data/sharelatex
docker run --rm -v sharelatex-mongo-data:/data mongo:6.0 mongodump --archive=/data/backup/mongo-$(date +%F).archive
这套方案同时覆盖了文件系统和数据库。恢复的时候先解压整体目录,再执行 mongorestore,基本能把环境还原到任意时点。曾经我偷懒只 dump 数据库,结果文件存储里的图片和附件全丢了,那次教训换来的经验是:备份永远不要只备一半。
3.2 环境版本核对清单
升级前把宿主机环境仔细过一遍,别等容器启动失败才回头看:
- Docker Engine 版本建议 24.x 以上,Compose v2 插件必须装好;
- 磁盘剩余空间至少 30GB,新镜像、编译缓存、日志增长都需要空间;
- 确认 80/443 端口没有被其他服务占用;
- 验证数据目录挂载权限,容器内 uid/gid 不一致会导致写入失败。
这些项看起来基础,但大量"升级后突然启动失败"的案例,最后都落在 Docker 版本太老、磁盘写满、路径权限不对这三处。
3.3 自定义配置的差异核对
如果之前对 Compose 文件做过大量个性化修改,升级前一定要逐个确认旧配置和新默认配置的差异。这里列几个最容易出问题的环境变量:
SHARELATEX_SITE_URL:站点对外 URL,改动后分享链接和邮件里的所有链接都会失效;SHARELATEX_LEFT_FOOTER/SHARELATEX_RIGHT_FOOTER:页脚信息,私有化部署通常会改成单位自己的名称;SHARELATEX_ALLOW_PUBLIC_ACCESS:是否允许匿名公共访问,想用分享链接功能必须设为true;- 编译超时相关变量:老版本调过的话,升级时要同步迁移到新版本对应的变量名。
我的习惯是把 docker-compose.yml 纳入 Git 管理,每次改动都提交。升级时直接拉出旧版本、对比官方新版模板、逐个确认差异,再动手改文件。这样即使出问题,也能快速定位是哪一项配置导致的。
4. 平滑升级实操:从旧版本切到 Overleaf 6.x
4.1 停服与清理旧容器
升级第一步是停掉全部旧服务。执行 docker compose down 会同时移除默认网络和容器,如果你在 Compose 里定义了外部网络,注意保留。我习惯分两步操作:
bash复制docker compose down --remove-orphans
docker ps -a | grep sharelatex
--remove-orphans 会把编排文件里已经删掉的旧容器一并清理,避免新旧容器名冲突。这个动作虽然简单,但能省去很多"新实例起不来"的麻烦。
4.2 更新编排文件并拉取新镜像
6.x 的镜像编排结构整体沿用了 5.x 的服务划分,主要变化在镜像 tag 和环境变量。把镜像地址从 sharelatex/sharelatex:5.x 改为 sharelatex/sharelatex:6.0.x,同时把 MongoDB 和 Redis 的版本按官方要求对齐。我整理的模板大概是这样的结构:
yaml复制services:
mongo:
image: mongo:6.0
volumes:
- mongo-data:/data/db
redis:
image: redis:7
sharelatex:
image: sharelatex/sharelatex:6.0.x
depends_on:
- mongo
- redis
environment:
- SHARELATEX_MONGO_URL=mongodb://mongo/sharelatex
- SHARELATEX_REDIS_HOST=redis
- SHARELATEX_SITE_URL=https://latex.example.edu.cn
- SHARELATEX_ALLOW_PUBLIC_ACCESS=true
volumes:
- sharelatex-data:/var/lib/sharelatex
ports:
- "80:80"
这里环境变量名用的是 SHARELATEX 前缀,这是社区版的一贯命名风格,沿用这个前缀可以避免老配置大改。如果你之前用的是全小写变量名,迁移时不要混用,否则容器会把变量解析为空,数据库都连不上。
4.3 启动并等待数据迁移完成
编排文件改好之后,直接拉镜像起服务:
bash复制docker compose pull
docker compose up -d
docker compose logs -f sharelatex
第一次启动时,web 容器会自动做数据库索引迁移和旧数据格式升级,这个过程通常需要 3 到 10 分钟,取决于项目数量。日志里看到类似 "Database migration complete" 的输出后,再访问站点测试登录和编译。
这里要特别提醒一点:如果项目数量很多,比如超过 2000 个,索引迁移可能拖到 20 分钟以上,期间站点显示 502 或加载缓慢是正常的,千万别中途重启容器。等日志彻底安静下来再继续操作。
4.4 升级后的验证清单
"站点能打开"不代表升级成功。我建议按这份清单逐项验收:
- 用管理员账号登录,确认用户列表和角色没有变化;
- 打开一个老项目,确认目录结构完整、已有编译产物还在;
- 新建一个最简单的
\documentclass{article}项目,确认能编译出 PDF; - 打开一个有中文内容的项目,确认 XeLaTeX 编译正常、字体不报错;
- 打开 Review 面板,确认修订历史记录没有丢失;
- 创建一个分享链接,用无痕窗口访问,确认匿名用户可以打开。
这六项全部通过,才算真正完成升级。以前我侥幸只测到第 3 项就收工,结果后面发现修订历史全丢失、中文编译报错,又花了大把力气翻日志恢复,那感觉十分酸爽。
4.5 回滚方案一定要提前想好
任何升级都要留退路。我把回滚方案固化成了两条:
- 如果只是启动失败或界面异常,把 compose 文件里的镜像 tag 改回旧版本,执行
docker compose up -d --force-recreate即可。挂载的sharelatex-data卷不会被覆盖,数据还在。 - 如果启动过程中已经执行了数据迁移、数据库结构被改变,那就必须用升级前的备份恢复。先把服务 down 掉,用备份目录和 MongoDB archive 文件还原到升级前状态,再用旧 tag 启动。
升级前不要急着删除旧镜像,磁盘够的话留着旧 tag,这就是最好的回滚保险。等新版本稳定运行一周再清理也不迟。
5. Overleaf 6.x 核心功能实测与调优
5.1 修订模式:多人改稿终于能留痕
Track Changes 是 Overleaf 被问得最多的功能之一,论文场景里导师和学生之间来回改稿,没有修订留痕会非常混乱。6.x 版本里这个功能的体验提升非常明显。
在编辑器右上角的 Review 面板里开启 Track Changes 后,新增内容会以带颜色的下划线标记,删除内容会以删除线标记,右侧可以按作者、操作类型筛选。接受或拒绝某条修订只需要点一下,修订历史永久保留。
我踩过一个实际坑:项目如果是在 5.x 时代创建的,升级到 6.x 后,老项目的修订历史有时不会自动显示在新面板里,需要去项目设置里重新激活 "Track changes" 视图。我一度以为历史丢了,后来发现只是默认折叠了。遇到修订历史不显示的情况,先别急着恢复备份,去 Review 面板设置里找开关。
5.2 分享链接:外协交流的正常操作方式
"分享链接"和"邀请协作者"这两个概念经常被混淆。区别其实很简单:邀请协作者是发邮件给指定用户,对方必须注册并登录;分享链接是生成一个公开 URL,拿到链接的人不用注册就能访问。
6.x 的链接分享权限分两档:
| 权限 | 适用场景 |
|---|---|
| Anyone with the link can view | 给期刊编辑、外审专家看审阅稿,只读即可 |
| Anyone with the link can edit | 临时拉外部人员参与编辑,对方无需注册 |
私有化部署想让链接分享生效,必须把 SHARELATEX_ALLOW_PUBLIC_ACCESS 设为 true,否则匿名用户访问链接会被强制跳转到登录页。这个点官方文档写得很隐蔽,我第一次没设置,还以为新版把功能砍了。
需要提醒的是,"任何人可编辑"意味着所有拿到链接的人都能改文档,所以在公开渠道留链接时,最好把权限控制在 view。用完记得去项目设置里关闭或调整链接权限。
5.3 编译超时与资源限制:核心痛点优先解决
编译超时大概是我在社区里被问到最多的问题。长文档、复杂 TikZ 图、大量 BibTeX 引用的项目,很容易超过系统默认超时时间,直接报 "Timed out"。
我在部署方案里做了两级调优。第一级调大超时时间,在 clsi 容器对应服务的环境变量里加入编译超时配置,把默认的 60 秒左右提到 300 秒。具体变量名在各版本中略有差异,一般是 CLSI_TIMEOUT 或 SHARELATEX_COMPILE_TIMEOUT 系列,升级到 6.x 后最稳妥的做法是查一下镜像仓库里的 README 确认最新命名。
第二级是资源保障。我给 clsi 容器设置了资源上限,限制内存 4GB、CPU 4 核,并确保编译容器不被其他服务挤占。实测一个 200 页带大量 TikZ 图的学位论文,资源充足时编译时间能从 2 分钟降到 40 秒左右。
如果是单机部署,还有一个性价比很高的操作:把 LaTeX 编译的临时文件目录挂载到内存盘(tmpfs),减少磁盘 IO 对编译速度的影响。改动之后小文档的编译速度提升非常明显。
6. 国内团队落地:从导入 zip 到环境调优的完整闭环
6.1 现有项目怎么迁移:zip 上传的正确姿势
在项目列表页点 "New Project" -> "Upload Project",选择本地 zip 压缩包,系统会自动解压并创建项目。也可以直接把 zip 拖拽到项目列表区域。
但打包上传有几个特别容易翻车的细节:
- 压缩包内不要混入嵌套的
.git目录或超大二进制文件,否则解析会非常慢; - zip 顶层目录结构最好保持单一项目,不要把多个项目的文件放在同一层级混合打包;
- 中文文件名编码要小心,Windows 下压缩的 zip 容易出现乱码,建议先把文件名统一转成 UTF-8 再打包。
如果你手头是 Git 仓库,更顺手的做法是用 Git 集成直接导入,项目在外部 Git 里做版本管理,Overleaf 只是编辑载体。这样既保留了团队已有的 Git 工作流,又能享受 Overleaf 的在线协作体验。
6.2 关于"国内怎么用",我的答案方向只有一个
总有人问"Overleaf 国内怎么用比较顺畅",我的回答是:要么用官方免费版能忍就忍,要么干脆私有化部署到国内节点,一步到位。官方版在国内体验不佳的根源是访问链路和编译资源调度,绕开这些问题的唯一系统性方案就是在本地跑一套自己的环境。
私有化部署到国内服务器,体验提升是质的飞跃:网站访问从跨洋链路变成局域网或国内直连,编译节点就在本地,不需要跟全球用户抢资源,也不存在编译排队问题。配合 Docker 镜像加速器,整个部署过程能控制在一小时以内。
这里多说一句镜像拉取。sharelatex/sharelatex 镜像在海外仓库,国内直接拉取很慢。一个有效的优化是给 Docker 配置 registry mirror,在 /etc/docker/daemon.json 里添加国内加速地址:
json复制{
"registry-mirrors": ["https://docker.mirrors.example.com"]
}
配置完成后执行 systemctl restart docker 再拉镜像,速度会有明显提升。这一步对国内部署来说是刚需,否则光拉一个几百 MB 的镜像就能等到失去耐心。
6.3 中文字体与内部模板:自建环境最容易忽略的两件事
官方 Overleaf 的编译环境内置了不少中文字体,但私有化部署的镜像默认情况下中文支持并不完整,常见表现是用 XeLaTeX 编译中文文档时报查找字体失败。
解决办法是往 clsi 容器里补齐中文字体。最省事的是安装 Noto CJK 系列字体,开源、覆盖全、无版权风险。可以在 Dockerfile 里把字体文件 COPY 进去,也可以运行时把字体目录挂载到容器里的字体路径。装完重建容器再测试中文编译。
模板库同样重要。很多团队有统一的论文模板、课程报告模板,私有化部署后可以把这些模板直接放到服务器的模板目录,让所有用户在新建项目时直接看到团队内部模板。这比让大家每次上传文件、手动确认格式高效得多,也保证了输出规范的一致性。
6.4 HTTPS 与反向代理:自建环境不能省的一步
私有化部署如果只在内网用,HTTP 直接访问问题不大。但只要通过域名让成员远程访问,或者要接入统一认证,就必须把 HTTPS 配上。我的建议是在 Overleaf 前面架一层 Nginx 或 Caddy 做反向代理,证书用公共 CA 或单位内部 CA 都可以。
反向代理配置里最需要注意的是 WebSocket 支持。Overleaf 的实时编辑依赖 WebSocket 长连接,如果 Nginx 没配置 Upgrade 和 Connection 头,多人协作会表现为"保存不上去"或者"对方看不到我的光标"。这个坑我当时排查了一整个下午,最后发现就是少了两个 proxy_set_header 行。
7. 升级后的排查实录与避坑清单
7.1 高频问题速查表
| 症状 | 常见原因 | 排查动作 |
|---|---|---|
| 站点打不开 | 端口占用或容器未启动 | docker compose ps 查看状态,ss -lntp 查端口 |
| 登录失败 | Mongo 连接配置错误 | 检查 SHARELATEX_MONGO_URL 是否正确 |
| 编译超时 | 文档太大或默认超时太短 | 调大超时设置,增加编译资源限制 |
| 中文编译报错 | 容器内缺少中文字体 | 安装 Noto CJK 等字体后重建容器 |
| 分享链接无法访问 | ALLOW_PUBLIC_ACCESS 未开启 |
设为 true 后重启 web 容器 |
| 修订历史不显示 | 视图开关未打开 | Review 面板设置里重新激活显示 |
| 多人协作不同步 | Nginx 未配置 WebSocket 头 | 补上 Upgrade 和 Connection 头 |
| 升级后容器写入失败 | 数据目录权限变更 | chown -R 1000:1000 /data/sharelatex |
7.2 两个印象最深的故障实录
第一个是 MongoDB 索引问题。5.x 升级到 6.x 后,老项目里的某些查询突然变得极慢,一次操作要等几十秒,最后定位是 MongoDB 里新版本需要的索引没有自动创建。解决方法是手动触发索引重建,或者对 sharelatex 数据库执行一次 `re
