第 1 章 Docker 基础:镜像与容器概念、安装配置与常用命令

好,咱们正式开始。做宏基因组流程最头疼的是什么?内存炸、环境乱、版本冲突。Docker 就是来解决这些问题的——把分析工具和依赖打包成一个轻量级“盒子”,扔到哪都能跑。我私下里管它叫“科研人员的集装箱”,装好一次,到处复制。

1.1 镜像与容器——搞清楚这两个“孪生兄弟”

新手上路最容易搞混的就是镜像和容器。我的经验是:用面向对象的思维去理解——镜像就是类(Class),容器就是实例(Instance)。说白了,镜像是静态的只读模板,容器是运行中的动态环境。

镜像(Image):一个分层文件系统,包含操作系统、软件、依赖、配置,但不包含进程。你从 Docker Hub 拉下来的一个几百 MB 文件,就是镜像。

容器(Container):镜像运行起来后的实体,有自己的文件系统、网络栈、进程空间。你可以对容器做修改,但停止或删除后这些修改就没了——除非你 docker commit 把它变成新镜像。

对比维度镜像(Image)容器(Container)
生命周期长期存在,可复用启动→运行→停止→删除
可变性只读可写(但不会写回镜像)
存储位置本地或远程仓库运行时在宿主机内存+磁盘
典型操作docker pull / docker builddocker run / docker stop

我记得有一次组里同事在服务器上直接改了个容器里的 Python 脚本,然后容器挂了。他想重新启动,结果发现之前切碎的新版没保存——唉,这就是没理解“容器修改不回写”的后果。从那以后我逢人就讲:任何对环境的持久化改动,都要通过 Dockerfile 或 docker commit 来管理。

1.2 安装与配置——别让第一步卡住

Docker 安装不算难,但不同系统有坑。我个人建议:优先用 Linux 做宿主,因为 Docker 原生跑在 Linux 内核上。Windows 和 macOS 都是通过虚拟化层跑的,性能有损耗,而且共享目录的权限问题能让你怀疑人生。

Linux(Ubuntu 为例)

用官方仓库装,别用系统自带的老版本。我曾经贪方便 apt install docker.io,结果版本太旧不支持 --gpus 参数,白白折腾半天。

# 卸载旧版
sudo apt remove docker docker-engine docker.io containerd runc

# 安装依赖
sudo apt update
sudo apt install ca-certificates curl gnupg

# 添加 Docker 官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 添加软件源
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker Engine
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 验证安装
sudo docker run hello-world
⚠️ 避坑: 每次都要加 sudo 很烦?把我的用户加入 docker 组就行。注意,加入 docker 组后等于让用户拥有 root 权限,生产环境慎用。
sudo usermod -aG docker $USER
newgrp docker   # 或者重新登录

macOS / Windows

去 docker.com 下载 Docker Desktop 安装包,一路下一步。注意 Windows 要开启 WSL 2 后端,不然性能差到你怀疑人生。我个人的建议是:如果只是做测试,用 Desktop 就够了;但要是跑生产级别的宏基因组流程,建议在 Linux 服务器上部署 Docker Engine。

1.3 常用命令入门——够用就行

命令不用全背,记住这几组就够你完成 80% 的工作。我习惯把命令分成三块:镜像管理、容器管理、仓库交互。

镜像管理

docker images                        # 查看本地镜像列表
docker pull ubuntu:22.04             # 从 Docker Hub 拉取镜像
docker rmi ubuntu:22.04              # 删除本地镜像
docker build -t myimage:1.0 .        # 用 Dockerfile 构建镜像

容器管理

docker run -it --name mycontainer ubuntu:22.04 bash   # 启动并进入交互式终端
docker ps [-a]                      # 查看运行中的(或所有)容器
docker stop mycontainer             # 停止容器
docker rm mycontainer               # 删除容器
docker exec -it mycontainer bash    # 进入已运行的容器

仓库交互

docker login                        # 登录 Docker Hub
docker push myrepo/myimage:1.0      # 推送镜像到仓库
docker pull myrepo/myimage:1.0      # 从仓库拉取

💡 我的习惯: 给容器起个有意义的名字(--name),不要靠随机生成的 id 来区分。宏基因组流程容器我一般叫 metagenomics_pipeline_v1,一目了然。

关于命令还有一个坑:docker run 和 docker start 的区别。前者是 创建并启动 一个新容器,后者是 重新启动 一个已停止的旧容器。我第一次做批量处理时写了个脚本循环 docker run,结果每次都是新容器,导出数据全丢在里面——嗯,后来改成了 docker start && docker exec 才解决问题。

知识体系一目了然

下面这张图是我画的 Docker 核心概念关系图。你看懂它,后面章节就不用再纠结基础细节了。

Docker 核心概念关系图 Docker Client docker pull / run / build ... Docker Daemon 管理镜像/容器/网络/存储 镜像 Image 只读模板 分层文件系统 Dockerfile 定义 容器 Container 运行中的实例 可读写层 进程隔离 镜像仓库 Registry Docker Hub / 私有仓库 分发和共享镜像 docker run docker commit docker pull docker push 底层支撑技术 Namespace(命名空间)→ 隔离进程/网络/文件系统 Cgroups(控制组)→ 限制 CPU/内存/IO 资源

📌 本章核心要点:

  • 镜像是静态模板,容器是动态实例——记住这个类比就够了。
  • 安装用官方源,Linux 优先;加 docker 组省 sudo,但注意安全。
  • 常用命令就三组:镜像管理、容器管理、仓库交互。不会的时候查 docker --help 就行。
  • 容器内修改不保存,要用 Dockerfile 或 docker commit 固化。