# 3. Docker常用命令:镜像管理、容器生命周期、网络和卷

Docker的命令行工具,说真的,是我们日常打交道最多的东西。你想想看,不管是拉镜像还是跑容器,几乎每步都离不开它。我个人习惯把这些命令分成四类:镜像管理、容器生命周期、网络和存储卷。搞清楚这四块,Docker基本就上手了。

Docker核心命令体系 镜像管理 pull / images / rmi / tag 容器生命周期 run / stop / rm / exec 网络管理 network ls / create / connect 存储卷 volume ls / create / inspect docker 命令行引擎 开发调试 docker exec -it CI/CD 自动化 docker build / push 生产部署 docker-compose up 核心思路:镜像不可变 → 容器可运行 → 网络可连通 → 数据可持久

3.1 镜像管理命令

说白了,镜像就是容器的“模板”。你拉一个镜像下来,才能用它起容器。我刚开始用Docker时,就靠下面这几个命令活着。

命令 作用 常用场景
docker pull 从仓库拉取镜像 下载 ubuntu:22.04、nginx:alpine
docker images 列出本地所有镜像 检查有哪些镜像可用
docker rmi 删除镜像 清理不再使用的旧镜像
docker tag 给镜像打标签 把本地镜像标记再推送
docker inspect 查看镜像元数据 排查镜像的配置和层信息

镜像管理里,我最常用的是 docker pull 和 docker images。先拉下来看看对不对,再决定删不删。我个人习惯用 docker images --format 来定制输出,只看我关心的字段。

docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

小技巧:docker system df 可以查看所有镜像、容器、卷占了多少磁盘空间。我每个月跑一次,清理那些悬空的镜像层。

注意:docker rmi 只能删除没有被容器使用的镜像。如果有容器还在用这个镜像,会报错。你先停容器,再删镜像。

3.2 容器生命周期管理

容器是镜像的“运行实例”。这一块命令最多,也是我们平时敲得最频繁的。我记得刚开始带团队时,有个同事总是记不清 docker start 和 docker run 的区别。嗯,这里我展开说说。

3.2.1 容器创建与启动

  • docker run:创建并启动一个新容器,等于 create + start 的合体。
  • docker create:只创建容器,不启动。
  • docker start/stop/restart:控制已创建容器的启停。
# 创建一个nginx容器,映射端口,并以守护模式运行
docker run --name my-nginx -d -p 8080:80 nginx:alpine

# 进入正在运行的容器,做调试或排查
docker exec -it my-nginx /bin/sh

# 查看容器日志
docker logs --tail 100 -f my-nginx

你想想看,docker run 背后其实做了好几件事:先检查本地有没有 nginx:alpine 这个镜像,没有就去拉,拉完才创建容器、启动容器、附加网络和存储。我在项目里遇到过有人反复用 docker run 来重启容器,结果发现容器 ID 每次都换,根本连不上。这其实是因为 run 每次都创建新实例,不是重启已有容器。

3.2.2 常用控制命令

操作 命令示例 说明
停止容器 docker stop my-nginx 优雅停止,发送 SIGTERM
强制停止 docker kill my-nginx 立刻杀死(SIGKILL)
启动已停止的容器 docker start my-nginx 不重建,直接用已有容器
删除容器 docker rm -f my-nginx -f 强制删除运行中的容器
列出容器 docker ps -a -a 显示所有状态

关键概念:容器一旦被删除,内部的所有变更都会丢失,除非你用了卷或commit。所以我在生产环境里,数据绝对不存容器内部。

3.3 网络管理

Docker默认的网络模式,说白了有三种:bridge、host、none。我个人最常用的是桥接模式,也是默认的。但多容器时,我建议你用 自定义bridge网络,因为内置的DNS解析功能可以让你直接通过容器名来访问,不用写IP。

# 创建一个自定义桥接网络
docker network create --driver bridge app-network

# 启动两个容器并连接到这个网络
docker run --name web --network app-network -d nginx
docker run --name db --network app-network -d postgres

# 在web容器里可以直接ping db,而不是写IP
docker exec web ping db

踩坑记录:我曾经在生产环境忘记指定网络,两个服务放在默认bridge里,结果靠IP地址通信。后来容器重启后IP变了,服务直接断掉。从那以后,我只要是多容器通信,一律用自定义网络 + 容器名访问。

3.4 存储卷管理

容器的文件系统是临时性的。容器删了,数据也就没了。所以数据持久化的核心就是 卷(Volume) 和 绑定挂载(Bind Mount)。我推荐优先用卷,因为卷由Docker管理,跨平台更安全。

存储方式 特点 适用场景
卷(Volume) Docker管理,存储在宿主机特定目录 数据库、日志持久化
绑定挂载(Bind Mount) 直接挂载宿主机的目录或文件 开发时热重载、配置文件
tmpfs 挂载 存储在内存中,容器停止即消失 敏感凭证、临时缓存
# 创建卷
docker volume create mydata

# 启动容器挂载卷
docker run -d --name pg -v mydata:/var/lib/postgresql/data postgres:16

# 挂载宿主机目录(用于开发调试)
docker run -d --name dev -v $(pwd)/app:/app nginx

避坑指南:绑定挂载时,如果宿主机目录不存在,Docker会自动创建,但创建的是目录不是文件。我曾经想挂载一个配置文件,路径写错了没报错,结果容器里挂了一个空目录,服务启动失败。排查了我快一个小时。

嗯,回过头来看,命令再多也离不开这几个核心逻辑:镜像 pull 下来 → run 成容器 → 容器用网络通信 → 数据用卷持久化。你把这几个命令记熟,日常开发基本够用了。