最近发现 Overleaf 在 GitHub 上开源了自己的服务端实现,仔细一看其实就是合并之前 ShareLaTeX 开源的版本的新版,甚至在 DockerHub 上面的名字都还是 sharelatex/sharelatex
。刚好某组织有搭建一个版本用于测试的需求,因为我以前自己搭过 ShareLaTeX,所以就帮忙一起配了一下。
实际上的过程非常简单:上面的仓库里面提供了一个 docker-compose.yml
,直接 pull 下来然后 docker-compose up
基本就结束了。官方提供的 教程 指出,镜像里面的 TeX Live 是不完整的。于是我在跑起来之后 docker exec
进容器中,安装了完整版的 TeX Live,放进去了中文字体,测试也一切正常。就在准备 commit 镜像之前,我想起来了一件事情:
以后镜像升级怎么办?
是的,官方把自己的服务和 TeX Live 直接打包了一个镜像里面,因此如果镜像有升级的话,用户做的任何改动必须重新来过(docker 有直接把一个 layer 覆盖在任意 layer 上的操作吗?有的话或许倒是可以弄一些黑魔法)。这显然会让我很不爽。思考了一下以后,我把镜像里面的这些目录复制了出来:
/usr/local/texlive
/usr/share/fonts
/var/cache/fontconfig
然后修改了一下 docker-compose
的配置,把它们加进了 sharelatex
容器的 data volume(也就是 bind mount)进去。这样,我们不用对原来的容器进行任何改动,就能够任意升级 TeX Live 版本、增加字体(别忘了跑一下 fc-cache
)了。
然而,又浮现出了一个新的问题:minted
宏包用不了。这是因为:
minted
宏包需要启用shell-escape
,而 TeX Live 默认没有启用;minted
宏包需要Pygments
Python 包的支持,并且需要pygmentize
脚本。
对于第一个问题,修改 Overlay 的 /usr/local/texlive/
,加入 shell_escape = t
即可。对于第二个问题,很幸运地,Pygments
宏包并没有什么依赖,因此我直接从 PyPI 下载了这个包,解压并将代码(pygments
目录)映射进容器的 /usr/lib/python3.6/
目录中,pygmentize
可执行文件映射进 /usr/bin
中。经过测试,minted
已经能够正常地运行了。
经过上面的魔改,一个比较科学的 Overleaf 服务就搭起来了。