第 1 章 Docker 基础:镜像与容器概念、安装配置与常用命令
好,咱们正式开始。做宏基因组流程最头疼的是什么?内存炸、环境乱、版本冲突。Docker 就是来解决这些问题的——把分析工具和依赖打包成一个轻量级“盒子”,扔到哪都能跑。我私下里管它叫“科研人员的集装箱”,装好一次,到处复制。
1.1 镜像与容器——搞清楚这两个“孪生兄弟”
新手上路最容易搞混的就是镜像和容器。我的经验是:用面向对象的思维去理解——镜像就是类(Class),容器就是实例(Instance)。说白了,镜像是静态的只读模板,容器是运行中的动态环境。
镜像(Image):一个分层文件系统,包含操作系统、软件、依赖、配置,但不包含进程。你从 Docker Hub 拉下来的一个几百 MB 文件,就是镜像。
容器(Container):镜像运行起来后的实体,有自己的文件系统、网络栈、进程空间。你可以对容器做修改,但停止或删除后这些修改就没了——除非你 docker commit 把它变成新镜像。
| 对比维度 | 镜像(Image) | 容器(Container) |
|---|---|---|
| 生命周期 | 长期存在,可复用 | 启动→运行→停止→删除 |
| 可变性 | 只读 | 可写(但不会写回镜像) |
| 存储位置 | 本地或远程仓库 | 运行时在宿主机内存+磁盘 |
| 典型操作 | docker pull / docker build | docker 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 核心概念关系图。你看懂它,后面章节就不用再纠结基础细节了。
📌 本章核心要点:
- 镜像是静态模板,容器是动态实例——记住这个类比就够了。
- 安装用官方源,Linux 优先;加 docker 组省 sudo,但注意安全。
- 常用命令就三组:镜像管理、容器管理、仓库交互。不会的时候查
docker --help就行。 - 容器内修改不保存,要用 Dockerfile 或
docker commit固化。