Docker 基础回顾:镜像、容器、仓库与常用命令
说实话,很多工程师一上来就急着跑 Isaac Sim,结果连 Docker 的基本概念都没搞清楚。我见过太多人在容器里折腾半天,最后发现是镜像没拉对,或者容器启动参数写错了。这一章,咱们把 Docker 的核心概念和常用命令捋一遍。别嫌基础,这些是后面所有操作的地基。
Docker 三大核心概念
Docker 的体系其实就三个东西:镜像、容器、仓库。搞懂它们的关系,你就能理解 Docker 为什么这么流行。
| 概念 | 类比 | 说明 |
|---|---|---|
| 镜像(Image) | ISO 安装盘 / 类模板 | 只读的、分层打包的文件系统,包含运行环境、依赖、代码 |
| 容器(Container) | 运行中的虚拟机实例 | 镜像的运行态,可读写、可启动、可停止、可删除 |
| 仓库(Registry) | GitHub / 应用商店 | 存储和分发镜像的地方,Docker Hub 是默认的公共仓库 |
我个人的理解方式: 镜像就是菜谱,容器就是按菜谱做出来的菜。菜谱可以反复用,菜吃完了可以重新做。仓库就是菜谱分享平台,你从上面下载别人写好的菜谱,也可以上传自己的。
这里有个关键点:镜像是分层的。每一层代表一个 Dockerfile 指令,层与层之间可以复用。我在项目中遇到过,有人把同一个基础镜像拉了三遍,白白浪费了磁盘空间和带宽。其实 Docker 的层缓存机制会自动复用已有的层,只要你没改前面的指令。
常用 Docker 命令速查
命令不用全背,但下面这几个你最好记在脑子里。我平时工作 80% 的时间都在用它们。
镜像操作
# 拉取镜像
docker pull nvidia/cuda:12.2.0-devel-ubuntu22.04
# 列出本地镜像
docker images
# 删除镜像
docker rmi nvidia/cuda:12.2.0-devel-ubuntu22.04
# 构建镜像(从 Dockerfile)
docker build -t my-isaac-sim:latest .
小技巧: 拉取 Isaac Sim 的镜像时,我建议先 docker pull 一个干净的 Ubuntu + CUDA 基础镜像,确认网络没问题,再拉完整的 Isaac Sim 镜像。否则你等半小时发现下载失败,心态会崩。
容器操作
# 创建并启动容器
docker run --gpus all -it --name isaac_container nvcr.io/nvidia/isaac-sim:latest
# 列出运行中的容器
docker ps
# 列出所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop isaac_container
# 启动已停止的容器
docker start isaac_container
# 进入容器内部
docker exec -it isaac_container /bin/bash
# 删除容器
docker rm isaac_container
嗯,这里要注意 docker run 和 docker exec 的区别。前者是创建新容器,后者是进入已有容器。我刚开始用的时候经常搞混,结果每次想进容器都重新创建了一个,搞得系统里一堆孤儿容器。
仓库与日志
# 登录仓库
docker login nvcr.io
# 推送镜像到仓库
docker push my-repo/isaac-sim:custom
# 查看容器日志
docker logs isaac_container
# 实时跟踪日志
docker logs -f isaac_container
Dockerfile 编写入门
Dockerfile 就是构建镜像的脚本。你想想看,如果每次都要手动装依赖、配环境,那跟传统部署有什么区别?Dockerfile 让这一切自动化、可重复。
下面是一个给 Isaac Sim 打基础用的 Dockerfile 示例:
# 使用官方基础镜像
FROM nvidia/cuda:12.2.0-devel-ubuntu22.04
# 设置环境变量,避免交互式安装
ENV DEBIAN_FRONTEND=noninteractive
# 安装系统依赖
RUN apt-get update && apt-get install -y \
wget \
git \
python3-pip \
libgl1-mesa-glx \
libegl1-mesa \
libxrandr2 \
libxss1 \
libxcursor1 \
libxcomposite1 \
libasound2 \
libxi6 \
libxtst6 \
&& rm -rf /var/lib/apt/lists/*
# 安装 Python 依赖
RUN pip3 install --upgrade pip && \
pip3 install numpy scipy matplotlib
# 创建工作目录
WORKDIR /workspace
# 复制本地文件(如果有)
# COPY ./scripts /workspace/scripts
# 默认命令
CMD ["/bin/bash"]
我曾经踩过的坑: 在 Dockerfile 里写 RUN apt-get update 但不写 apt-get install,或者写了 install 但忘了 rm -rf /var/lib/apt/lists/*。前者会导致缓存过期,后者会让镜像体积膨胀 200MB 以上。记住:update 和 install 要写在同一行,并且清理缓存。
Dockerfile 指令速查表
| 指令 | 作用 | 使用频率 |
|---|---|---|
FROM |
指定基础镜像 | 必用 |
RUN |
执行命令(构建时) | 高频 |
COPY / ADD |
复制文件到镜像 | 高频 |
WORKDIR |
设置工作目录 | 推荐使用 |
ENV |
设置环境变量 | 高频 |
EXPOSE |
声明容器端口 | 中频 |
CMD |
默认启动命令 | 必用 |
ENTRYPOINT |
容器入口点 | 中频 |
我的习惯: 尽量用 COPY 而不是 ADD。ADD 会自动解压 tar 包,有时候会带来意想不到的行为。明确的事情用明确的指令,这是工程师的素养。
Docker 核心工作流
下面这张图展示了 Docker 从构建到运行的全流程。我每次给团队新人讲 Docker,都会先画这张图。
说白了,Docker 就是把你整个运行环境打包成一个「镜像」,然后到处跑。你不需要关心宿主机装了什么库、什么版本,只要 Docker 能跑,你的应用就能跑。这就是为什么 Isaac Sim 这种依赖复杂、对 GPU 驱动有严格要求的软件,用 Docker 部署是最优雅的方式。
总结一下本章的核心:
- 镜像(Image)是只读模板,容器(Container)是运行实例,仓库(Registry)是镜像市场
- 掌握
docker pull/run/exec/ps/stop/rm这六个命令,你就能应付 90% 的日常操作 - Dockerfile 的关键是
FROM、RUN、COPY、CMD,记住「层缓存」和「清理缓存」两个原则