做科研或者写技术文档的人,应该都体会过配置本地 LaTeX 环境的痛苦。宏包冲突、字体缺失、编译报错,处理这些问题的时间往往比真正写内容的时间还长。所以我最初接触 Overleaf 这类在线协作工具时,最大的感受就是“终于不用再折腾环境了”。不过,公共的 Overleaf 服务有两个绕不开的问题:文档托管在别人的平台上,涉及未公开的项目资料时心里不踏实;团队协作时又完全依赖外部链路,链路一旦出问题,整个写作流程就会卡住。基于这些考虑,我决定基于 Overleaf 开源社区版 ShareLaTeX-CE,做一次完整的私有化部署。这篇文章就把整个部署方案、配置要点和踩坑记录整理出来,希望对有同样需求的人有帮助。
这篇文章适合谁?一类是实验室、工作室或者小型团队,希望有一套自有的在线 LaTeX 协作平台;另一类是个人用户,不想把论文草稿和私人笔记放在公共平台上,想在自己的服务器上跑一套轻量服务。文章默认你有基本的 Linux 操作能力,会一点点 Docker 和 Nginx,即使不熟也没关系,关键步骤我都给了可直接复制执行的命令和配置。
1. 部署前先想清楚:ShareLaTeX-CE 到底适合哪些场景
1.1 公共在线服务与私有化的取舍
先说结论:如果只是偶尔写个简历、排个课程报告,公共在线平台完全够用,注册就能用,根本不用自己维护服务器。但一旦进入长期项目写作,比如论文、技术手册、课题结题报告,就会出现几个实际问题。
第一是数据归属。文档存在别人的服务器上,虽然平台有访问控制,但对团队内部未公开的资料来说,这始终是一个心理门槛。第二是账号和协作策略不可控。公共平台的免费账号有项目数量限制,成员管理也受制于平台规则,想加一个外部协作者还得看对方是否有账号。第三是链路质量。即使网络状况很好,跨地域访问在线编辑器的延迟也会影响体验,尤其是实时预览这种交互,响应慢一点就会很别扭。
私有化部署本质上是把这些问题搬回自己手里:数据放在自己的服务器,成员账号自己管理,访问域名自己控制,还能按需配置编译资源。付出的代价是你需要承担服务器成本、维护工作和偶尔的排障。对一个 5 到 20 人的团队来说,这个代价是划算的。
1.2 ShareLaTeX-CE 的范围和边界
ShareLaTeX-CE 是 Overleaf 团队开源出来的社区版,也是 Overleaf 这套产品的前身代码。它和公共版的核心写作体验基本一致:项目文件管理、多人实时编辑、编译预览、版本历史、评论系统都有。日常写 LaTeX 文档用得上的功能,社区版基本覆盖了。
需要注意的是它不包含公共版的某些高级能力,比如专业的组织级权限模型、细粒度的单点登录集成、更完善的管理后台指标面板。这些功能对个人用户和小团队影响很小,但如果你所在单位有合规性的强制要求,需要提前确认清楚。
另外,ShareLaTeX-CE 在官方 Docker 体系里是和编辑器、编译服务打包在一起的。也就是说,你部署出来的是一个整体服务,对外提供一个 Web 页面,用户通过浏览器完成全部操作,不需要在客户端安装任何 LaTeX 环境。这一点对团队协作特别友好,新成员加入后只要有一个浏览器就能立刻开始写作,彻底绕开了本地环境配置的问题。
1.3 单机部署还是微服务拆分
社区版的 Docker 部署方案本身是多个服务组件协作:Web 前端、文档存储、实时同步、编译执行。官方提供的 docker-compose 模板把这些服务做成了容器编排,默认就是一套单机可跑的组合。
很多人会问:要不要拆成微服务部署到多台机器上?以我实践下来的经验,绝大多数场景都不需要。单机部署的好处是部署简单、调试方便、备份容易;而拆成多服务之后,网络通信、服务发现、日志收集这些运维成本会立刻涨上来。只有当团队规模大到几十人以上,或者有高可用要求的时候,才值得考虑分布式方案。
我最终的选择是单机 Docker Compose 部署,搭配外部 Nginx 做 HTTPS 反向代理。这个方案兼顾了扩展性和维护成本,也是社区版最典型的部署方式。
2. 服务器与基础环境:4 核 8G 就能撑起小团队
2.1 资源配置量级评估
先给参考配置,再说我的分析逻辑。
| 配置项 | 最低要求 | 推荐配置 | 说明 |
|---|---|---|---|
| CPU | 2 核 | 4 核及以上 | 编译过程是 CPU 密集型,核数越多编译越快 |
| 内存 | 4 GB | 8 GB | 内存影响并发编译和系统响应,4G 只能带 1-2 人轻量使用 |
| 磁盘 | 20 GB | 50 GB 以上 | 镜像、缓存、历史版本、用户上传文件都会占用空间 |
| 网络 | 公网或内网可达 | 带宽按人数评估 | 多人同时编辑时 WebSocket 连接较多,但流量不大 |
我自己用的是一台 4 核 8G 的云服务器,跑一个小型团队大概 8 人同时在线,编译高峰时段系统负载还在可接受范围。如果团队成员超过 15 人,或者经常编译百页以上的大型文档,建议直接上 8 核 16G,省得后面再折腾迁移。
磁盘是个容易忽略的点。TeX Live 镜像本身就接近 2GB,再加上用户上传的图片、生成的文件快照,以及数据库的持续增长,50G 是一个比较宽裕的地板。我见过有人用 20G 磁盘跑了半年,最后扩容时折腾半天,所以建议一开始就留足余量。
2.2 Docker 与 Compose 安装
我的部署环境是 Ubuntu Server,Docker 的安装直接走系统包管理即可,不算复杂。
sudo apt update sudo apt install -y docker.io docker-compose-plugin sudo systemctl enable docker sudo systemctl start docker安装完成后验证一下版本:
docker --version docker compose version看到输出里有对应的版本号就说明环境准备好了。需要提一下,这里用的是 Docker Compose 插件版(docker compose 命令),不是旧版的 docker-compose 独立命令。两者语法基本一致,但插件版与新版 Docker 集成的更好,建议优先使用。
注意:不要为了方便直接在服务器上装图形化的容器管理面板。多一层工具就多一个安全面和维护点,命令行足够用。
2.3 目录规划与持久化原则
容器本身是无状态的,容器一删,里面的数据就没了。所以容器外的数据持久化必须在部署前规划好。我用的是下面这个目录结构:
/opt/overleaf/ ├── compose.yaml # Docker Compose 服务编排文件 ├── data/ # ShareLaTeX 应用数据目录 ├── mongo_data/ # MongoDB 数据目录 ├── redis_data/ # Redis 数据目录 └── backup/ # 备份脚本和备份文件所有服务的数据都通过 Docker 卷挂载到宿主机目录,这样无论容器怎么重建,数据都还在。这个思路其实就是把容器的“临时性”和数据的“持久性”分离开,运维的时候会省掉很多麻烦。
另外,在正式安装前,建议先给服务器做一次系统更新,把安全补丁打上。部署完服务后,还要记得在防火墙里只放行必要的端口,不要贪图省事把端口全部打开。
3. Docker Compose 部署实操:从拉镜像到 HTTPS 访问
3.1 获取部署模板并理解服务构成
ShareLaTeX-CE 的官方 Docker 部署模板可以从开源社区仓库拿到。不过我更推荐的做法是直接看官方文档中引用到的 compose 模板结构,然后自己整理一份精简的配置文件。原因是官方模板里环境变量特别多,很多参数对默认场景并不需要,自己写反而更清楚。
整个服务由三部分组成:ShareLaTeX 主服务、MongoDB(文档数据库)、Redis(缓存和实时同步支持)。主服务镜像内部已经包含了完整 TeX Live 发行版,不需要单独安装 LaTeX。首次启动时,主服务会自动完成环境初始化和内部数据库结构初始化。
3.2 编写 Compose 文件与关键环境变量
在 /opt/overleaf 目录下创建 compose.yaml,内容如下:
version: "3.8" services: overleaf: image: overleaf/sharelatex:latest container_name: sharelatex restart: always ports: - "8080:80" environment: SHARELATEX_APP_NAME: "Team Overleaf" SHARELATEX_SITE_URL: "http://127.0.0.1:8080" SHARELATEX_NAV_TITLE: "Overleaf" SHARELATEX_ADMIN_EMAIL: "admin@example.com" SHARELATEX_MONGO_URL: "mongodb://mongo/sharelatex" SHARELATEX_REDIS_HOST: "redis" SHARELATEX_REDIS_PORT: "6379" volumes: - /opt/overleaf/data:/var/lib/overleaf depends_on: - mongo - redis mongo: image: mongo:4.4 container_name: sharelatex-mongo restart: always volumes: - /opt/overleaf/mongo_data:/data/db redis: image: redis:6.2 container_name: sharelatex-redis restart: always volumes: - /opt/overleaf/redis_data:/data几个关键环境变量的作用需要理解清楚:
- SHARELATEX_SITE_URL:整个服务对外访问的完整地址。如果你打算用域名加 HTTPS 访问,部署完成后要改成 https 的地址,否则页面里的资源链接会走错协议。
- SHARELATEX_ADMIN_EMAIL:管理员账号邮箱。系统不会单独弹一个“初始化管理员”的页面,你在这个平台注册的第一个账号就是管理员。这个邮箱主要用于提示信息和找回密码。
- SHARELATEX_MONGO_URL:MongoDB 的连接串。这里用的是 compose 内部网络里的服务名 mongo,不需要映射到宿主机端口。
- volumes:将容器内的数据目录挂载到宿主机,保证容器重建后数据不丢。
注意:MongoDB 版本选择 4.4 是因为 ShareLaTeX-CE 官方模板长期以 4.4 作为默认版本。盲目追新用 MongoDB 7.x,反而可能出现兼容性警告。
3.3 启动服务与首次登录验证
配置文件准备好以后,直接启动:
cd /opt/overleaf docker compose pull docker compose up -d第一条命令会从镜像仓库拉取三个镜像,ShareLaTeX 主镜像比较大,包含完整 TeX Live,拉取时间取决于网络质量。拉取完成后,第二条命令会在后台启动所有服务。
启动后先看日志,确认服务是否正常初始化:
docker compose logs -f overleaf日志中出现类似服务启动完成、监听端口的提示,就说明主服务没问题。再过十几秒,浏览器访问 http://服务器IP:8080 ,应该能看到 Overleaf 的欢迎页面。注册第一个账号并登录,新建一个空白项目,编译一个最简单的文档:
\documentclass{article} \begin{document} Hello, Overleaf! \end{document}编译成功看到 PDF 输出,整个部署流程就走通了。
3.4 Nginx 反向代理与 HTTPS 配置
直接暴露 8080 端口虽然方便,但不推荐。生产环境要做的第一件事是把服务放到 HTTPS 后面,避免文档内容和登录信息在网络上明文传输。我用 Nginx 做反向代理,将 443 端口的 HTTPS 流量转发到本机的 8080。
Nginx 的配置如下:
server { listen 80; server_name latex.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name latex.example.com; ssl_certificate /etc/ssl/overleaf/fullchain.pem; ssl_certificate_key /etc/ssl/overleaf/privkey.pem; client_max_body_size 100m; 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; } location /socket.io { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } }这里有几个细节要特别说明。
第一是 /socket.io 这个路径。Overleaf 的实时协作和光标同步依赖 WebSocket 长连接,如果不在 Nginx 层支持协议升级,多人同时编辑时会出现内容不同步、光标不移动这类诡异问题。这个是新手最容易漏掉的一点。
第二是证书问题。TLS 证书可以申请免费的即可,我的习惯是先用脚本工具完成证书签发和自动续期。证书文件放在 /etc/ssl/overleaf/ 下,并在 Nginx 配置里引用。
第三,配置生效后,要把 compose.yaml 里的 SHARELATEX_SITE_URL 改成实际域名,然后重启容器:
docker compose up -d这样整个服务就算正式上线了。之后团队访问的就是一个以域名开头的 HTTPS 站点,看着像模像样,用起来也踏实。
4. 常见问题与调优实录:超时、字体、备份一次讲透
4.1 编译超时与大文档优化
部署完最大的抱怨通常来自编译超时。默认配置下,单个项目的编译时间是有限制的,平时写写课程报告没问题,但一碰到几百页的厚文档,或者包含大量 TikZ 图片的项目,编译就会卡到超时。
我的实际做法分两步。第一步,进入运行中的 ShareLaTeX 容器,找到配置文件中的编译超时参数,把它从默认值调大。具体操作是从容器内修改配置文件,然后重启容器。第二步,从使用习惯上优化文档结构,把大文档拆成多个子文件,用 \input 或 \include 组织起来。这样既能分散编译压力,也方便多人分工编辑同一份文档的不同章节。
另外还有一个小技巧是清理不用的宏包和临时文件。很多模板会把用不到的功能全堆在导言区,每次编译都要加载一遍,累积起来耗时明显。把用不到的宏包注释掉,编译速度会有可感知的提升。
4.2 镜像拉取慢的应对方案
即使网络状况不错,拉取 ShareLaTeX 主镜像时也可能遇到速度慢甚至超时的情况。毕竟镜像是打包好的 TeX Live 环境,体积摆在那里。
如果你遇到拉取速度问题,优先检查有没有正确配置 registry mirror。Docker 的镜像加速配置位于 /etc/docker/daemon.json,添加 registry mirror 后重启 Docker 服务即可。
如果镜像源速度还是不理想,还有一个离线方案:在另一台网络条件较好的机器上执行 docker pull,把镜像保存成 tar 文件,再传到目标服务器上用 docker load 导入。这个方式适合服务器和外部仓库之间链路不稳定的场景。我实际用过几次,整个过程比干等下载要快得多。
4.3 中文字体与宏包支持
ShareLaTeX-CE 镜像自带 TeX Live,里面包含大量常用宏包和字体,但中文字体通常不在默认集合里。直接默认使用 ctex 宏包是可以的,但如果你要编译含有特殊中文字体的文档,就需要手动把字体装进容器里。
我的做法是:先把字体文件复制到容器中,再找到 TeX Live 的 texmf-local 目录,在 fonts/truetype 下建立字体目录,最后执行 mktexlsr 刷新字体映射。
常见的坑是,某些 Windows 环境下做的模板用到了系统字体名,而容器里的中文字体名并不完全一致。这时候最简单的办法是统一改用 ctex 宏包默认字体,或者把手头的中文字体以 font name 的方式注册进去。真正遇到具体问题,重点先确认字体文件是否被 TeX 扫描到,再去查字体名映射。
4.4 数据备份与服务器迁移
私有化部署的另一个价值是数据可控,但这也意味着备份责任完全在自己身上。我的备份策略是双管齐下:数据库备份 + 文件目录备份。
数据库备份使用 mongodump,在 compose 环境中直接执行:
docker compose exec mongo mongodump --archive=/data/backup/sharelatex-mongo-$(date +%F).gz --gzip --db sharelatex文件目录备份则直接压缩挂载在宿主机上的 /opt/overleaf/data 目录:
tar -czf /opt/overleaf/backup/overleaf-data-$(date +%F).tar.gz /opt/overleaf/data我建议把备份命令写成一个脚本,配合系统的定时任务定期执行。这样即便服务器突然出问题,也能在最多 24 小时内恢复到最近一次备份点。
迁移服务器时,只要新机器上装好 Docker 和 Compose,拷贝备份文件,恢复数据库和文件目录,再重新拉起容器即可。整个迁移过程可以在半小时内完成,这一点在团队协作场景里非常重要。
我在实际部署里遇到过一次磁盘告警,找原因时才发现是版本历史数据积累过多。这个问题的根源在于 Overleaf 会保存文档的多个历史版本,如果团队改动频繁,这部分数据增长是很快的。遇到这种情况,优先考虑扩容,其次定期清理不需要保留的旧版本。具体来说,保留最近 90 天的版本记录通常已经足够,更早的版本可以归档到外部存储,没必要一直占着主磁盘空间。这个操作可以加在备份脚本里一起完成,省心不少。
最后再分享一个经验:部署这套平台之后,维护工作其实比想象中少,真正花时间的反而是团队成员的适应过程。只要把管理员账号、备份策略和常用问题整理成一份简单的团队说明,大部分日常问题都能内部消化。如果计划在公司或实验室落地,我建议先在真实项目里试用两周,确认编译环境和常用宏包覆盖到位,再正式推开。经过这几周的磨合,你会和我一样,彻底告别本地 LaTeX 环境的那些糟心事。