1. Docker 基础:Docker 简介与核心概念

第一次接触Docker是在一个单细胞分析项目上。当时我需要在三台不同实验室的服务器上跑同样的Seurat流程,环境依赖搞得我焦头烂额。后来我用了Docker,用一个命令就把整个分析环境搬到了另一台机器上。嗯,今天我们就从最基础的东西开始聊。

1.1 Docker 到底是什么?

说白了,Docker就是一种“轻量级虚拟机”。但它不模拟硬件,而是共享宿主机内核,只把应用程序和它需要的依赖(库、配置文件、系统工具)打包在一起。这个打包好的单元叫“容器”。

我印象最深的是这样一个场景:有个同事在CentOS上开发了一个R包分析流程,我自己的电脑是Ubuntu,直接跑各种报错。用Docker后,他的环境被完整打包成镜像,我拉下来就能跑,省了整整两天调试时间。

Docker与传统虚拟机的核心区别:

  • 虚拟机:包含完整操作系统,重量级,启动分钟级
  • Docker容器:共享宿主机内核,轻量级,启动秒级

1.2 三个核心概念

学Docker其实就是在理解这三个东西:镜像、容器、仓库。我习惯把它们类比成面向对象编程里的类、实例、代码仓库。

概念类比一句话解释
镜像类只读模板,包含操作系统、软件、依赖
容器对象镜像的运行实例,可读写、可删除
仓库GitHub存储和分发镜像的地方(比如Docker Hub)
⚠️ 注意:镜像一旦构建就是只读的。容器里的修改如果要保留,必须提交成新镜像或挂载数据卷。我曾经因为忘记挂载卷,熬夜跑完的分析结果随着容器删除一起消失……从那以后再也不敢了。

1.3 Docker 镜像分层结构

镜像为什么能这么轻?因为它采用了分层文件系统。每个指令(比如安装一个包)会生成一层,这些层可以复用。比如两个镜像都基于Ubuntu 22.04,那底层就共用同一份,只在上层叠加不同的软件。

为什么会这样?因为Docker使用联合文件系统(UnionFS)把多个只读层合并成一个逻辑文件系统。我认识一个搞生信的同事,他的RNA-seq镜像从300MB减到120MB,就是通过合并RUN指令减少层数做到的。

1.4 常用的 Dockerfile 指令

构建镜像靠的是Dockerfile。我推荐你从一开始就掌握这几个最常用的指令:

# 基础镜像,我习惯用官方标签带版本号
FROM ubuntu:22.04

# 维护者信息(现在推荐用LABEL)
LABEL maintainer="yourname@example.com"

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    python3 \
    r-base \
    curl

# 设置工作目录
WORKDIR /workspace

# 复制本地文件到镜像
COPY scripts/ /workspace/scripts/

# 暴露端口(仅供文档说明,容器间通信还需要-p)
EXPOSE 8787

# 默认启动命令
CMD ["Rscript", "/workspace/run.R"]
💡 个人建议:每写一个RUN指令就清理一次缓存,比如 apt-get clean && rm -rf /var/lib/apt/lists/*。否则镜像体积会膨胀得离谱。我踩过最大的坑就是忘记了,结果一个900MB的镜像光缓存就占了300MB。

1.5 容器数据持久化:卷与挂载

容器默认是无状态的——你删掉容器,里面的数据也就没了。数据必须保存在宿主机上,这就要用卷(Volumes)或绑定挂载(Bind Mounts)。

# 创建一个数据卷
docker volume create sc_data

# 启动容器时挂载卷
docker run -v sc_data:/data sc_analysis_image

# 或者绑定挂载宿主机目录
docker run -v /home/user/data:/data sc_analysis_image

我个人更喜欢用数据卷,因为Docker会自动管理它的位置,而且能在不同容器间共享。绑定挂载更适合开发阶段频繁改代码的场景。

1.6 Docker 网络模式

容器之间怎么通信?Docker提供几种网络模式:

  • bridge(默认):每个容器有独立IP,通过docker0网桥通信。适合单机单容器。
  • host:容器直接使用宿主机网络,没有隔离。性能好但安全性差。
  • none:不给容器任何网络,完全隔离。
  • 自定义网络:我常用的方式,用 docker network create 创建,容器间可通过名字互相访问。

拿空间单细胞分析来说:你可能会同时启动一个R容器跑Seurat和一个Python容器跑Scanpy,它们需要共享同一个数据目录并互相调用API。这时候自定义网络 + 数据卷是最稳的组合。

1.7 一张图看懂 Docker 核心架构

下面这张SVG图是我用Docker时的思维模型,帮新同事理解最快。建议你先看整体结构,再细抠每个部分。

Docker 核心架构图 宿主机操作系统 (Linux内核 + 硬件) Docker 引擎 (Docker Daemon + REST API) 容器 A Seurat + R 4.2 数据卷: /workspace 容器 B Scanpy + Python 3.10 数据卷: /workspace 容器 C Cell Ranger 无数据卷 镜像仓库 (Docker Hub / 私有Registry) 关键说明 1. 容器共享宿主机内核,不虚拟机的方式 2. 镜像层是只读的,容器启动时在镜像上加可写层

1.8 本章小结

我们搞懂了Docker为什么是生信分析的最佳拍档——轻量、可复现、环境隔离。核心概念就三个:镜像、容器、仓库。我还分享了我个人的一些坏习惯和踩坑经历,希望你能少走弯路。

一句话记住:Docker 让你像管理代码一样管理你的分析环境。对于一个空间单细胞项目来说,这意味着你可以把整个分析流水线(从原始fastq到最终可视化的R环境)固化成一个镜像,无论换到哪台服务器都能一秒拉起来跑。嗯,这就是Docker的魅力。