3、Docker基础命令:镜像管理与容器生命周期
好,咱们直接进入正题。Docker 的命令行工具,说白了就是你跟 Docker 引擎对话的「遥控器」。我见过不少新手,一上来就 docker run,出了问题就懵了。其实把基础命令理清楚,后面的大多数场景都能应付。
这一章,我带你过一遍最核心的几组命令。镜像管理、容器生命周期、还有怎么进到容器里面去。嗯,都是每天要用的。
3.1 镜像管理:你的「应用模板」仓库
镜像是什么?你可以把它理解成一个「只读的模板」。里面装好了操作系统、运行环境、还有你的应用代码。容器就是基于这个模板跑起来的实例。
3.1.1 docker pull:把镜像拉下来
没有镜像,容器就无从谈起。docker pull 就是从远程仓库(默认是 Docker Hub)把镜像下载到本地。
docker pull nginx:latest
docker pull ubuntu:20.04
docker pull registry.cn-hangzhou.aliyuncs.com/library/nginx:1.21
我个人习惯,拉镜像时一定指定版本标签。为什么?因为 latest 是个「移动靶」,你今天拉的和下周拉的可能是不同版本。我在项目中遇到过,测试环境用的 latest 没问题,生产环境一部署就报错——因为镜像被更新了。从那以后,我所有脚本里都写死版本号。
3.1.2 docker images:看看本地有啥
拉下来的镜像都存在本地。用 docker images 查看。
docker images
# 或者简写
docker image ls
输出会显示仓库名、标签、镜像ID、创建时间和大小。你想想看,如果本地镜像越来越多,磁盘空间就吃紧了。这时候就需要清理。
3.1.3 docker rmi:删掉不需要的镜像
删除镜像用 docker rmi。可以跟镜像名:标签,也可以跟镜像ID。
docker rmi nginx:1.21
docker rmi f6509fac4982 # 用镜像ID删除
我曾经在清理服务器时,一口气删了十几个镜像,结果发现有个容器还在用其中一个。嗯,docker rm 之后才搞定。所以建议你先用 docker ps -a 看看有没有关联容器。
3.1.4 docker tag:给镜像打标签
docker tag 就是给镜像起个别名。常用于把本地镜像标记成私有仓库的格式,方便推送。
docker tag nginx:latest myregistry.com/myproject/nginx:v1.0
说白了,tag 不会复制镜像数据,只是创建了一个「引用」。你删掉原标签,新标签还能用。我经常用这个命令来管理不同环境的镜像版本。
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:后台运行(detach模式)--name:给容器起个名字,方便管理-p:端口映射,宿主机端口:容器端口
如果不加 -d,容器会在前台运行,你的终端就被「占住」了。按 Ctrl+C 会停止容器。我刚开始学的时候,经常忘了加 -d,结果终端一关容器就没了。
3.2.2 docker start / stop:启停容器
容器创建后,可以用 start 和 stop 来控制它的运行状态。
docker start my-nginx
docker stop my-nginx
docker stop 会给容器发送 SIGTERM 信号,让容器优雅退出。如果 10 秒内没响应,就发 SIGKILL 强制杀死。你可以用 docker stop -t 30 来调整等待时间。
我记得有一次,生产环境的容器里跑着长任务,直接 stop 导致数据没写完。后来我改成先发信号通知应用做清理,再 stop 容器。嗯,这就是「优雅关闭」的思路。
3.2.3 docker rm:删除容器
容器停止后,它还在磁盘上占着空间。用 docker rm 彻底删除。
docker rm my-nginx
docker rm -f my-nginx # 强制删除运行中的容器
我建议你定期清理不用的容器。用 docker container prune 可以一键删除所有已停止的容器。省得手动一个个删。
3.3 进入容器:跟里面的世界交互
有时候你需要进到容器里面,看看日志、调试问题、或者执行一些命令。Docker 提供了两种方式:exec 和 attach。
3.3.1 docker exec:在容器里执行命令
docker exec 是在运行中的容器里「新开一个进程」。最常用的场景是启动一个交互式 Shell。
docker exec -it my-nginx /bin/bash
# 或者用 sh(如果容器里没有 bash)
docker exec -it my-nginx sh
-it 是两个参数的组合:-i 保持标准输入打开,-t 分配一个伪终端。少了任何一个,你都没法正常交互。
我个人习惯用 exec 而不是 attach。为什么?因为 exec 不会影响容器的主进程。你退出 Shell,容器还在跑。attach 就不一样了。
docker exec my-nginx env。想看看进程?docker exec my-nginx ps aux。exec 可以执行任意命令,非常灵活。
3.3.2 docker attach:连接到容器的主进程
docker attach 是连接到容器正在运行的主进程。说白了,就是把你当前的终端「粘」到容器的标准输入输出上。
docker attach my-nginx
这里有个坑:如果你用 attach 连上去,然后按 Ctrl+C,这个信号会直接发给容器的主进程。如果主进程是 Nginx,它可能就退出了。容器也就停了。
我曾经在调试时,用 attach 连上去看日志,习惯性地按了 Ctrl+C,结果容器直接挂了。嗯,从那以后我基本只用 exec。
3.4 实战小总结
好了,这一章的内容其实就这些。我帮你理一下思路:
| 操作 | 命令 | 说明 |
|---|---|---|
| 拉取镜像 | docker pull | 指定版本标签,避免 latest 陷阱 |
| 查看镜像 | docker images | 定期清理无用镜像 |
| 删除镜像 | docker rmi | 先删容器,再删镜像 |
| 打标签 | docker tag | 用于私有仓库推送 |
| 创建并运行 | docker run | 记住 -d 后台运行 |
| 启停容器 | docker start/stop | stop 会优雅关闭 |
| 删除容器 | docker rm | 加 -f 强制删除 |
| 进入容器 | docker exec | 推荐用 exec,别用 attach |
这些命令,你每天都会用到。我建议你打开终端,跟着敲一遍。别光看,动手才是硬道理。下一章,我们会聊 Dockerfile 的编写,到时候这些命令就是你的基本功了。