3、Docker基础命令:镜像管理与容器生命周期
好,咱们直接进入正题。Docker 的命令说多不多,说少不少。但真正日常高频使用的,其实就是镜像管理和容器生命周期这两块。我刚开始接触 Docker 时,也试图背下所有命令,后来发现没必要——把核心的十几个命令用熟,就能覆盖 90% 的工作场景。
这一章,咱们就聚焦在这两类命令上。你跟着我敲一遍,基本就记住了。
3.1 镜像管理命令
镜像是什么?说白了就是容器的「模板」。你要跑一个容器,得先有这个镜像。就像你要做菜,得先有菜谱一样。
3.1.1 docker pull:拉取镜像
这是你接触 Docker 后用的第一个命令。从远程仓库(默认是 Docker Hub)把镜像下载到本地。
docker pull nginx:latest
docker pull ubuntu:22.04
docker pull registry.cn-hangzhou.aliyuncs.com/library/nginx:1.21
我个人习惯,拉镜像时尽量指定具体版本标签,而不是用 latest。为什么?因为 latest 是个动态标签,今天拉的和明天拉的可能是不同版本。我在项目中遇到过,测试环境用的 latest,生产环境也用的 latest,结果某天镜像更新后,测试通过了但生产挂了——因为两个环境拉取的时间点不同。嗯,从那以后,我所有脚本里都写死了版本号。
3.1.2 docker images:查看本地镜像
拉下来之后,怎么确认有没有成功?用 docker images 查看本地镜像列表。
docker images
# 或简写
docker image ls
输出结果会显示仓库名、标签、镜像 ID、创建时间和大小。你想想看,如果本地镜像越来越多,这个列表会变得很长。我一般会配合 grep 来过滤:
docker images | grep nginx
这样只显示跟 nginx 相关的镜像,清爽多了。
3.1.3 docker rmi:删除镜像
镜像占磁盘空间,尤其是那些调试用的临时镜像。用 docker rmi 删除不需要的镜像。
docker rmi nginx:1.21
docker rmi 镜像ID
注意:如果某个镜像正在被容器使用,你是删不掉的。Docker 会提示你「有容器依赖这个镜像」。这时候你得先删容器,再删镜像。我曾经犯过这个错——想清理空间,结果删不掉,还以为是命令出问题了。
docker ps -a 查看所有容器(包括已停止的)。
3.1.4 docker tag:给镜像打标签
这个命令很实用。你可以给一个镜像打上多个标签,方便管理。比如,你从官方拉了一个 nginx:latest,想把它标记成自己仓库的版本:
docker tag nginx:latest myregistry.com/mynginx:v1.0
这样,你后续推送镜像到私有仓库时,就用这个新标签。我个人习惯,在 CI/CD 流程中,每次构建完镜像都会打上两个标签:一个是版本号(如 v1.2.3),一个是 latest。这样既方便回滚,也方便开发环境使用。
3.2 容器生命周期命令
镜像有了,接下来就是跑容器。容器的生命周期,说白了就是:创建→运行→停止→删除。这四个阶段对应四个核心命令。
3.2.1 docker run:创建并启动容器
这是最常用的命令,没有之一。docker run 等于先 docker create 再 docker start,一步到位。
docker run -d --name my-nginx -p 8080:80 nginx:1.21
解释一下参数:
-d:后台运行(detached mode)。不加的话,终端会被容器日志占满。--name:给容器起个名字。我建议每次都起名,不然 Docker 会随机生成一个名字,比如focused_curie,你根本记不住哪个是哪个。-p:端口映射。宿主机端口:容器端口。
我记得刚学 Docker 时,经常忘记加 -d,结果一关终端容器就停了。后来养成了习惯,生产环境必加 -d,调试时才不加。
docker run 如果指定的镜像本地没有,会自动执行 docker pull。但我不建议依赖这个自动拉取行为——显式 pull 更可控。
3.2.2 docker start:启动已存在的容器
容器创建后如果停止了,可以用 docker start 重新启动。注意,它不会重新创建容器,只是把已有的容器跑起来。
docker start my-nginx
这个命令我用的场景不多,更多是在调试时:先 docker stop 停掉,改完配置再 docker start 启动。但说实话,现在我更倾向于删掉容器重新 docker run,因为这样更干净。
3.2.3 docker stop:停止容器
停止一个运行中的容器。Docker 会给容器发送 SIGTERM 信号,让它优雅退出。如果超时(默认10秒)还没停,就发 SIGKILL 强制杀死。
docker stop my-nginx
docker stop -t 30 my-nginx # 自定义超时时间
你想想看,为什么要有优雅退出?因为有些应用需要做清理工作,比如保存状态、关闭数据库连接。我曾经遇到过,直接 docker kill 导致数据丢失的情况。所以,能用 stop 就别用 kill。
3.2.4 docker rm:删除容器
容器停止后,它还在磁盘上占着空间。用 docker rm 彻底删除。
docker rm my-nginx
docker rm -f my-nginx # 强制删除运行中的容器
我一般会定期清理不用的容器:
docker rm $(docker ps -aq) # 删除所有已停止的容器
注意,-f 参数会直接杀死容器再删除,相当于 docker kill + docker rm。慎用。
3.3 常用命令组合速查表
为了方便你日常查阅,我把这些命令整理成了一张表。你可以保存下来,忘了就瞄一眼。
| 命令 | 作用 | 常用参数 | 使用频率 |
|---|---|---|---|
docker pull |
拉取镜像 | 指定版本标签 | ⭐⭐⭐⭐ |
docker images |
查看本地镜像 | 配合 grep 过滤 | ⭐⭐⭐⭐ |
docker rmi |
删除镜像 | 镜像名或 ID | ⭐⭐⭐ |
docker tag |
打标签 | 源镜像:标签 目标镜像:标签 | ⭐⭐⭐ |
docker run |
创建并启动容器 | -d, --name, -p, -v | ⭐⭐⭐⭐⭐ |
docker start |
启动已停止的容器 | 容器名或 ID | ⭐⭐ |
docker stop |
停止容器 | -t 超时时间 | ⭐⭐⭐⭐ |
docker rm |
删除容器 | -f 强制删除 | ⭐⭐⭐ |
3.4 避坑指南
最后,分享几个我踩过的坑,你遇到了能少走弯路。
- 镜像越拉越多,磁盘爆了:我建议每周执行一次
docker system prune,它会清理所有未使用的镜像、容器和网络。但注意,它会删掉所有未被容器引用的镜像,如果你有需要保留的,先确认好。 - 容器名冲突:如果你
docker run时用了已经存在的容器名,Docker 会报错。要么删掉旧容器,要么换个名字。我习惯在名字后面加日期,比如my-nginx-20240101,避免冲突。 - 端口被占用:启动容器时如果端口映射冲突,Docker 会直接报错退出。先用
lsof -i :端口号检查端口占用情况,再决定用哪个端口。
好了,这一章的内容就这些。镜像管理和容器生命周期是 Docker 操作的基础,你把这几个命令练熟了,后续的镜像构建、编排部署才能顺手。下一章,咱们聊聊 Dockerfile 的编写技巧——那才是真正体现功力的地方。