可重复性实践:Docker与Nextflow结合 - 第1节
1. Docker 起源与核心概念
说起 Docker,我最早接触是在 2015 年。那时我在做一个生物信息学分析流程,环境依赖简直是个噩梦——Python 2.7 vs 3.5、R 版本冲突、某个 C 库非要特定的 glibc 版本。当时团队里有个同事神秘兮兮地说:「试试 Docker,装好一次,到处跑。」我半信半疑试了试,结果一发不可收拾。
Docker 这个项目最初是 dotCloud 公司(后来改名为 Docker Inc.)内部的一个小工具。2013 年开源,借助 Linux 内核的 cgroups 和 namespaces 技术,实现了轻量级的操作系统级虚拟化。说白了,它不像虚拟机那样需要模拟整个操作系统,而是直接共享宿主机的内核,只把进程、文件系统、网络等隔离起来。
为什么这很重要?因为它让「环境一致性」变得极其简单。你在笔记本上构建的容器,放到服务器、云端甚至同事的电脑上,行为完全一致。
1.1 镜像、容器、仓库——三剑客
理解 Docker 要抓住三个核心概念:镜像(image)、容器(container)、仓库(registry)。
- 镜像:一个只读的模板,包含操作系统文件、应用程序及其所有依赖。你可以把它想象成「软件安装包」的 snapshot。
- 容器:从镜像启动的运行实例。它可在镜像上加一层可写层,所有修改都写在这一层,不影响原始镜像。
- 仓库:存储和分发镜像的地方。最出名的是 Docker Hub,但你可以搭建私有仓库。
举个例子:我经常用 biocontainers 镜像跑 NGS 分析。拉取一次 quay.io/biocontainers/bwa:0.7.17,这个镜像就缓存在本地。每次启动一个容器,bwa 的环境是固定不变的。我的分析流程再也不会因为服务器升级而莫名报错。
1.2 Docker 的应用场景
Docker 的应用场景比你想象的多。这里列几个我实际踩过坑的领域:
| 场景 | 为什么用 Docker | 我的经历 |
|---|---|---|
| 科研可重复性 | 封装整个分析环境,包括工具、库、系统补丁 | 曾经审稿时作者提供了 Dockerfile,我直接拉取运行,结果完全一致。这种论文我打高分。 |
| CI/CD 流水线 | 每个构建任务跑在干净容器里,避免环境污染 | 在 Jenkins 上用 Docker 做并行测试,速度提升 3 倍。 |
| 微服务架构 | 每个服务独立容器,独立扩展 | 公司从单体迁移到微服务,全靠 Docker Compose 做本地编排。 |
| 桌面开发环境 | 在 Mac/Windows 上模拟 Linux 环境 | 我开发 Nextflow 流程时,所有测试都在容器里运行,避免污染宿主系统。 |
嗯,你可能会问:「那 Docker 有没有缺点?」有的。比如需要 root 权限(现在有 rootless 模式了),磁盘占用可能膨胀,网络性能略低于原生。但总的来说,在可重复性实践中,它的利远大于弊。
2. 安装配置实战
下面说说在不同操作系统上安装 Docker。我按自己的实战经验讲,不列官方文档的废话。
2.1 Linux(Ubuntu 22.04 为例)
Linux 安装最顺畅,因为 Docker 本来就是 Linux 原生的。我建议用官方仓库,别用系统自带的过时版本。
# 卸载旧版本
sudo apt remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl
# 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# 添加仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 启动并设置开机自启
sudo systemctl enable docker --now
装完后验证:
sudo docker run hello-world
如果能打印出 Hello from Docker! 说明成功。注意:默认需要 sudo。我习惯把当前用户加入 docker 组,省得每次敲 sudo。
sudo usermod -aG docker $USER
newgrp docker
2.2 macOS
Mac 上需要安装 Docker Desktop,它是一个带 UI 的完整环境。我用的是 Intel Mac,但 Apple Silicon 用户要注意版本。
- 从 Docker官网 下载 Docker Desktop for Mac(根据芯片选择 ARM64 或 x86_64)
- 双击安装,把 Docker.app 拖到 Applications 文件夹
- 启动后在系统栏会出现鲸鱼图标,等它显示「Docker Desktop is running」
- 打开终端验证:
docker version
我曾经踩过一个坑:在 Mac 上跑 Docker 默认使用 HyperKit 虚拟机,磁盘空间容易爆满。后来我改用新的 Apple Virtualization 框架(Docker Desktop 4.3+),才解决了这个问题。如果你用 M1/M2 芯片,记得勾选「Use VirtioFS」来提升文件共享性能。
2.3 Windows
Windows 安装推荐使用 WSL 2 后端。这是目前最丝滑的方式。
- 确保安装了 WSL 2(Windows 10 2004+ 或 Windows 11)
- 安装 Docker Desktop for Windows,安装时勾选「Use WSL 2 based engine」
- 重启后,在 Docker Desktop 设置中将默认 WSL 发行版设为 Ubuntu(或其他你常用的)
- 打开 PowerShell 运行
docker run hello-world
有个细节:Windows 上文件系统性能差异很大。把项目代码放在 WSL 的 Linux 文件系统下(比如 /home/yourname/project)比放在 /mnt/c/Users/... 快得多。我在做 NGS 流程测试时,这个改动让运行时间缩短了 40%。
3. 知识体系一览
下图概括了本章的核心逻辑——从容器原理解释到安装配置的整个脉络。