4. Dockerfile编写入门:构建第一个MaxQuant镜像
说实话,我第一次用Docker跑MaxQuant的时候,心里也没底。那会儿还在用虚拟机,每次换个版本就重新配一遍环境,折腾得够呛。后来发现Dockerfile就是一份「安装说明书」,写好之后,不管在谁的电脑上都能复现一模一样的环境。
这一节,我会带你手写一个能跑MaxQuant 2.1.0.0的Dockerfile。过程不复杂,但有几个关键坑——嗯,我当年都踩过。
4.1 先理解MaxQuant需要什么
MaxQuant毕竟是.NET框架下的Win Forms应用,在Linux上跑需要Mono运行时。另外它调用底层算法依赖一些原生库。说白了,我们需要这三样东西:
- Ubuntu系统(我用20.04 LTS,稳)
- Mono运行时(版本≥6.12,我建议用官方源装)
- MaxQuant程序包(从官网下,或者自己之前存好的安装包)
你想想看,这三样东西组合起来,就是一个能运行MaxQuant的容器了。
4.2 为什么不用apt-get直接装MaxQuant?
我猜你会问:Ubuntu官方源里不是有maxquant-dev包吗?对,是有的。但我个人习惯是自己构建镜像,原因很简单——源里的版本通常滞后半年到一年,而且你没法同时保留多个版本。自己做Dockerfile,想切哪个版本就切哪个版本。
一句话总结:自己写Dockerfile = 版本自由 + 环境可控 + 部署可复现。
4.3 写一个基本的Dockerfile
我们分阶段来。第一阶段先把环境搭好,第二阶段放MaxQuant本体。
下面是我现在项目里用的模板,去掉了无关的调试部分:
# ============================================================
# 阶段一:基础镜像
# ============================================================
FROM ubuntu:20.04 AS base
# 避免安装时弹出时区交互
ENV DEBIAN_FRONTEND=noninteractive
# 更新源并安装必要工具
RUN apt-get update && apt-get install -y \
curl \
wget \
gnupg \
ca-certificates \
lsb-release \
--no-install-recommends
# 添加Mono官方源(注意:一定要用官方源,不要用系统源)
RUN wget https://packages.mono-project.com/repo/ubuntu/dists/focal/main/binary-amd64/Packages.gz \
-O /tmp/mono-packages.gz && \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \
--recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" \
> /etc/apt/sources.list.d/mono-official-stable.list
# 安装Mono运行时
RUN apt-get update && apt-get install -y \
mono-complete \
--no-install-recommends
# ============================================================
# 阶段二:运行时阶段(尽量小体积)
# ============================================================
FROM ubuntu:20.04 AS runtime
ENV DEBIAN_FRONTEND=noninteractive
# 只复制运行时需要的Mono组件
COPY --from=base /usr/lib/mono /usr/lib/mono
COPY --from=base /usr/bin/mono /usr/bin/mono
COPY --from=base /usr/lib/x86_64-linux-gnu/libgdiplus.so* /usr/lib/x86_64-linux-gnu/
# 创建MaxQuant工作目录
WORKDIR /opt/maxquant
# 复制MaxQuant程序(假设你已经有压缩包)
COPY maxquant-2.1.0.0-linux-x64.tar.gz /opt/maxquant/
RUN tar xzf maxquant-2.1.0.0-linux-x64.tar.gz && \
rm maxquant-2.1.0.0-linux-x64.tar.gz
# 设置入口点
ENTRYPOINT ["mono", "/opt/maxquant/MaxQuant.exe"]
小技巧:我在项目中经常把MaxQuant程序包放在构建上下文外的一个目录,然后用docker build --build-arg MQ_VERSION=2.1.0.0传入版本号。这样同一个Dockerfile可以构建出任意版本。
4.4 构建镜像与运行
写好Dockerfile之后,构建就很简单了:
# 构建镜像,注意最后的点(构建上下文)
docker build -t maxquant:2.1.0.0 -f Dockerfile .
# 等待几分钟(取决于网速)
# 构建成功后,查看镜像
docker images
# 输出长这样(仅供参考,实际tag和ID不同)
# REPOSITORY TAG IMAGE ID CREATED SIZE
# maxquant 2.1.0.0 a1b2c3d4e5f6 2 minutes ago 1.85GB
镜像构建好了,怎么跑得快?我一般试一个最简单的测试:
# 查看帮助
docker run --rm maxquant:2.1.0.0 --help
# 正常输出(如果构建正确):
# MaxQuant 2.1.0.0
# Command-line mode
# Usage: mono MaxQuant.exe [options]
4.5 避坑指南:我遇到过的问题
我曾经第一次构建完镜像,一运行就报错:
System.TypeLoadException: Could not load type 'System.Runtime.InteropServices.RuntimeInformation'
后来查了才知道,Mono的版本太低了。我用的Ubuntu源自带的mono-complete只有5.8版本,而MaxQuant 2.1需要Mono ≥ 6.12。解决方法就是像我上面那样用Mono官方源,不要用系统源。
还有一个坑:有的MaxQuant版本需要libgdiplus。如果你在容器里跑图像相关的功能但没装这个库,程序会直接无声终止。解决办法就是在Dockerfile里复制那个.so文件,或者用apt-get装libgdiplus。
警告:如果你在网上复制别人的Dockerfile,一定检查Mono源的地址。一些老教程里用的download.mono-project.com/repo/debian,那是Debian的源,Ubuntu不能用。Ubuntu必须用stable-focal(20.04)或stable-jammy(22.04)。
4.6 多版本管理的思路
现在你已经有能力构建一个版本的镜像了。如果你想同时保留2.0.1、2.1.0、2.3.0这几个版本,怎么做?很简单:
- 每个版本一个Dockerfile(或者用构建参数)
- 镜像tag里带上版本号
- 需要哪个版本就运行对应的容器
具体做法我在下一节会详细展开。这里你只要记住:Dockerfile是版本控制的锚点,版本切换就是改一行tag的事。
4.7 本章核心流程图
下面这张SVG图总结了从Dockerfile到运行MaxQuant的完整路径。你可以对照着回顾每一步之间的关系。
4.8 本章小结
写一个能跑MaxQuant的Dockerfile,没那么玄乎。记住三件事:
- Base镜像选Ubuntu 20.04,兼容性好,我试过22.04也没问题,但20.04最稳
- Mono一定要用官方源,版本≥6.12,低于这个版本MaxQuant会报TypeLoadException
- 分阶段构建,把编译环境跟运行环境分开,镜像能小不少(我见过不这样做的镜像有3GB)
创建运行MaxQuant的容器环境之后,下一轮的挑战其实在配置文件和输入文件的挂载。不过那是后面的事了——先把这一步跑通,你就已经迈过最大的坎了。