5.1 Docker 命令结构总览
Docker 命令通常由三部分组成:
1docker <子命令> <操作> [选项] [参数]
常见子命令分组:
| docker image | 镜像管理 | pull、images、rmi、tag、save、load |
| docker container | 容器管理 | run、ps、stop、start、rm、exec、logs |
| docker volume | 数据卷管理 | create、ls、inspect、rm |
| docker network | 网络管理 | create、ls、inspect、connect |
| docker system | 系统维护 | df、prune、info |
| docker compose | 多容器编排 | up、down、ps、logs、exec |
说明:docker images、docker ps、docker rmi 等是传统简写命令,仍然广泛使用;docker image ls、docker container ls 等新写法语义更清晰,两者功能基本等价。
5.2 环境与版本检查
安装完成后,第一步通常是确认 Docker 是否正常工作。
1docker –version
2# 查看 Docker 客户端版本
3
4docker version
5# 查看客户端和服务端版本信息,用于排查兼容问题
6
7docker info
8# 查看 Docker 系统信息,包括容器数、镜像数、存储驱动、磁盘位置等
如果 docker info 能正常输出,说明 Docker 引擎已经就绪。
5.3 镜像管理命令
镜像是容器的"模板"。容器由镜像启动,所以先要会管理镜像。
5.3.1 拉取镜像:docker pull
1docker pull nginx
2# 拉取 nginx 最新镜像
3
4docker pull nginx:1.27
5# 拉取指定版本,生产环境更推荐指定明确版本
6
7docker pull mysql:8.0
8# 拉取 MySQL 8.0 镜像
9
10docker pull redis:7-alpine
11# 拉取基于 Alpine 的轻量 Redis 镜像
建议:生产环境尽量不要使用 latest 标签。latest 会随时间变化,可能导致升级后出现兼容性问题。
5.3.2 查看本地镜像:docker images
1docker images
2# 列出本地所有镜像
3
4docker images -a
5# 查看所有镜像,包括中间层
6
7docker images -q
8# 只输出镜像 ID,常用于批量操作
输出示例:
1REPOSITORY TAG IMAGE ID CREATED SIZE
2nginx 1.27 a1b2c3d4e5f6 2 weeks ago 180MB
3mysql 8.0 7f8e9d0a1b2c 1 month ago 520MB
4redis 7-alpine 3c4d5e6f7a8b 3 weeks ago 45MB
5.3.3 删除镜像:docker rmi
1docker rmi nginx:1.27
2# 删除指定镜像
3
4docker rmi -f nginx:1.27
5# 强制删除,即使有容器正在使用该镜像(谨慎使用)
6
7docker image prune
8# 清理没有标签的悬空镜像
9
10docker image prune -a
11# 清理所有未被容器使用的镜像(危险,生产环境慎用)
5.3.4 镜像标签:docker tag
1docker tag nginx:1.27 my-registry.com/nginx:1.27
2# 为已有镜像添加新标签,常用于推送前改名
5.3.5 导出与导入镜像
1docker save -o nginx-1.27.tar nginx:1.27
2# 将镜像导出为 tar 文件,适合离线迁移
3
4docker load -i nginx-1.27.tar
5# 从 tar 文件导入镜像
5.4 容器生命周期管理
容器是镜像的运行实例。掌握容器生命周期,是日常使用 Docker 的核心。
5.4.1 创建并运行容器:docker run
docker run 是最常用、参数最多的命令。建议重点掌握。
1docker run nginx
2# 前台运行 nginx 容器,会占用当前终端
更常用的组合:
1docker run -d –name web -p 8080:80 nginx:1.27
2# -d:后台运行
3# –name web:给容器命名为 web
4# -p 8080:80:将宿主机 8080 端口映射到容器 80 端口
5# nginx:1.27:使用指定版本镜像
常用参数说明:
| -d | 后台运行 | 长期运行的服务 |
| –name | 指定容器名 | 方便后续 stop、logs、exec |
| -p 宿主机端口:容器端口 | 端口映射 | Web 服务、数据库对外访问 |
| -v 宿主机路径:容器路径 | 绑定挂载 | 配置文件、代码目录、数据持久化 |
| -v 卷名:容器路径 | 命名卷挂载 | 数据库数据持久化 |
| -e KEY=VALUE | 设置环境变量 | 数据库密码、API 密钥 |
| –restart | 重启策略 | 服务宕机后自动恢复 |
| –rm | 退出后自动删除 | 临时调试容器 |
| –network | 指定网络 | 多容器互联 |
| –memory / –cpus | 限制资源 | 防止单个容器占满资源 |
5.4.2 重启策略:–restart
1docker run -d –name web –restart unless-stopped nginx:1.27
2# 除非手动停止,否则 Docker 重启或容器异常退出时都会自动拉起
常见策略:
| no | 不自动重启 |
| on-failure | 仅在非零退出码时重启 |
| always | 总是重启 |
| unless-stopped | 总是重启,除非手动停止 |
建议:生产服务推荐使用 unless-stopped;开发调试可用 no 或 on-failure。
5.4.3 查看容器:docker ps
1docker ps
2# 查看正在运行的容器
3
4docker ps -a
5# 查看所有容器,包括已停止的
6
7docker ps -q
8# 只输出容器 ID
9
10docker ps -n 5
11# 查看最近创建的 5 个容器
5.4.4 停止、启动、重启、删除容器
1docker stop web
2# 优雅停止容器,发送 SIGTERM 信号
3
4docker start web
5# 启动已停止的容器
6
7docker restart web
8# 重启容器
9
10docker kill web
11# 强制停止容器,发送 SIGKILL 信号
12
13docker rm web
14# 删除已停止的容器
15
16docker rm -f web
17# 强制删除运行中的容器
18
19docker container prune
20# 批量删除所有已停止的容器
区别:stop 是优雅停止,容器内进程有机会清理资源;kill 是立即终止,适合容器卡死或无响应的情况。
5.5 进入容器与执行命令
5.5.1 进入容器:docker exec
1docker exec -it web bash
2# 进入正在运行的容器,获得交互式终端
3
4docker exec -it redis-container sh
5# 如果镜像没有 bash,可使用 sh(Alpine 镜像常见)
6
7docker exec -it web -u root bash
8# 以 root 身份进入容器
参数说明:
- -i:保持标准输入打开
- -t:分配伪终端
- -u root:以 root 用户执行
5.5.2 不进入容器直接执行命令
1docker exec web nginx -v
2# 在容器内执行单条命令,不进入终端
3
4docker exec web ls /app
5# 查看容器内 /app 目录内容
5.5.3 docker exec 与 docker attach 的区别
| docker exec -it | 在运行中容器内启动新进程 | 调试、查看文件、执行命令 |
| docker attach | 附加到容器主进程的标准输入输出 | 查看前台进程输出 |
建议:日常排查优先使用 docker exec。docker attach 退出时可能影响容器主进程,风险更高。
5.6 日志查看与资源监控
5.6.1 查看日志:docker logs
1docker logs web
2# 查看容器日志
3
4docker logs -f web
5# 实时跟踪日志
6
7docker logs –tail 100 web
8# 查看最近 100 行日志
9
10docker logs -f –tail 200 web
11# 实时跟踪最近 200 行日志
12
13docker logs -t web
14# 显示时间戳
15
16docker logs –since "2026-10-09T10:00:00" web
17# 查看指定时间之后的日志
场景:容器启动失败、接口报错、数据库连接异常时,第一步通常是 docker logs -f –tail 200 容器名。
5.6.2 资源监控:docker stats
1docker stats
2# 实时监控所有容器的 CPU、内存、网络、磁盘 IO
3
4docker stats web
5# 只监控指定容器
6
7docker stats –no-stream
8# 只输出一次快照,适合脚本采集
输出示例:
1CONTAINER CPU% MEM USAGE / LIMIT NET I/O BLOCK I/O
2web 0.50% 45.2MiB / 2GiB 1.2kB/0B 0B/0B
5.6.3 查看容器详细信息:docker inspect
1docker inspect web
2# 查看容器详细配置,包括 IP、挂载、环境变量、日志路径等
3
4docker inspect –format '{{.NetworkSettings.IPAddress}}' web
5# 只提取容器 IP 地址
场景:排查端口映射是否正确、数据卷是否挂载成功、环境变量是否生效时,docker inspect 非常有用。
5.7 端口映射:-p 参数详解
端口映射是把容器内服务暴露给宿主机或外部网络的关键。
5.7.1 基本端口映射
1docker run -d -p 8080:80 nginx:1.27
2# 宿主机 8080 → 容器 80
访问方式:http://localhost:8080
5.7.2 指定宿主机 IP 绑定
1docker run -d -p 127.0.0.1:8080:80 nginx:1.27
2# 只允许本机访问,外部无法直接访问
场景:数据库、Redis、管理后台等不建议直接对外暴露的服务,可以绑定 127.0.0.1。
5.7.3 映射多个端口
1docker run -d \\
2 -p 8080:80 \\
3 -p 8443:443 \\
4 –name web \\
5 nginx:1.27
6# 同时映射 HTTP 和 HTTPS 端口
5.7.4 随机端口映射
1docker run -d -P nginx:1.27
2# Docker 自动分配宿主机端口
3
4docker port web
5# 查看实际分配的端口
5.7.5 端口映射合理性建议
| Nginx / Web 前端 | -p 80:80、-p 443:443 | 对外提供 HTTP/HTTPS 服务 |
| Spring Boot / Node.js | -p 8080:8080 | 避免与宿主机 80 端口冲突 |
| MySQL | -p 127.0.0.1:3306:3306 | 不建议直接对外暴露 |
| Redis | -p 127.0.0.1:6379:6379 | 配合密码认证使用 |
| 临时调试 | -P | 让 Docker 自动分配端口 |
5.8 数据持久化:-v 与数据卷
容器默认是"无状态"的,删除容器后内部数据会丢失。持久化数据有两种常用方式。
5.8.1 绑定挂载:-v 宿主机路径:容器路径
1docker run -d \\
2 –name web \\
3 -p 8080:80 \\
4 -v /home/user/nginx/html:/usr/share/nginx/html \\
5 nginx:1.27
6# 将宿主机目录挂载到容器内,修改宿主机文件后容器内同步生效
场景:开发环境代码热加载、Nginx 配置文件注入、日志目录挂载。
5.8.2 命名卷:-v 卷名:容器路径
1docker volume create mysql-data
2# 创建命名卷
3
4docker run -d \\
5 –name mysql \\
6 -p 127.0.0.1:3306:3306 \\
7 -e MYSQL_ROOT_PASSWORD=123456 \\
8 -v mysql-data:/var/lib/mysql \\
9 mysql:8.0
10# 使用命名卷持久化 MySQL 数据
查看卷信息:
1docker volume ls
2# 列出所有数据卷
3
4docker volume inspect mysql-data
5# 查看卷在宿主机上的真实路径
6
7docker volume prune
8# 清理未使用的数据卷
5.8.3 两种持久化方式对比
| Bind Mount | 挂载宿主机具体目录 | 开发代码目录、配置文件 |
| Named Volume | Docker 管理的卷 | 数据库、缓存、生产数据 |
| tmpfs | 内存中存储,容器停止后消失 | 临时缓存、敏感临时文件 |
5.9 文件传输:docker cp
1docker cp web:/etc/nginx/nginx.conf ./nginx.conf
2# 从容器复制文件到宿主机
3
4docker cp ./index.html web:/usr/share/nginx/html/index.html
5# 从宿主机复制文件到容器
场景:容器内没有 vim、curl 等工具时,可以先 docker cp 把文件复制出来修改,再复制回去。
5.10 网络管理入门
5.10.1 查看网络
1docker network ls
2# 列出所有网络
3
4docker network inspect bridge
5# 查看默认桥接网络详情
5.10.2 创建自定义网络
1docker network create app-net
2# 创建自定义桥接网络
3
4docker run -d –name web –network app-net nginx:1.27
5# 将容器加入自定义网络
6
7docker run -d –name api –network app-net my-api:1.0
8# 同一网络中的容器可通过容器名互相访问
优势:自定义网络内置 DNS 解析,容器之间可以直接通过容器名通信,比默认 bridge 网络更清晰。
5.11 系统维护与清理
5.11.1 查看磁盘占用
1docker system df
2# 查看镜像、容器、数据卷、构建缓存占用的磁盘空间
5.11.2 清理无用资源
1docker container prune
2# 删除所有已停止的容器
3
4docker image prune
5# 删除悬空镜像
6
7docker volume prune
8# 删除未使用的数据卷
9
10docker system prune
11# 清理已停止容器、未使用网络、悬空镜像
12
13docker system prune -a –volumes
14# 彻底清理,包括未使用镜像和数据卷(危险,生产慎用)
5.12 多项目类型实战示例
场景 1:Nginx 静态网站
1# 拉取镜像
2docker pull nginx:1.27
3
4# 准备静态页面
5mkdir -p /home/user/site
6echo "<h1>Hello Docker</h1>" > /home/user/site/index.html
7
8# 启动容器
9docker run -d \\
10 –name my-site \\
11 -p 8080:80 \\
12 -v /home/user/site:/usr/share/nginx/html \\
13 nginx:1.27
14
15# 验证
16curl http://localhost:8080
说明:修改 /home/user/site/index.html 后,刷新浏览器即可看到变化,无需重启容器。
场景 2:MySQL 数据库
1# 创建数据卷
2docker volume create mysql-data
3
4# 启动 MySQL
5docker run -d \\
6 –name mysql \\
7 -p 127.0.0.1:3306:3306 \\
8 -e MYSQL_ROOT_PASSWORD=123456 \\
9 -v mysql-data:/var/lib/mysql \\
10 –restart unless-stopped \\
11 mysql:8.0
12
13# 查看日志
14docker logs -f –tail 100 mysql
15
16# 进入容器执行 SQL
17docker exec -it mysql mysql -uroot -p123456
说明:即使删除容器,只要 mysql-data 卷还在,数据就不会丢失。重新创建容器时再次挂载该卷即可恢复数据。
建议:生产环境不要使用 123456 这种弱密码,也不要将 -e MYSQL_ROOT_PASSWORD=… 直接写在命令行中(会被 history 记录)。推荐使用环境变量文件或 Docker Secret 管理敏感信息。
场景 3:Redis 缓存服务
1# 启动 Redis,开启持久化并设置密码
2docker run -d \\
3 –name redis \\
4 -p 127.0.0.1:6379:6379 \\
5 -v redis-data:/data \\
6 –restart unless-stopped \\
7 redis:7-alpine \\
8 redis-server –requirepass mypassword –appendonly yes
9
10# 进入 Redis CLI
11docker exec -it redis redis-cli -a mypassword
12
13# 测试
14docker exec -it redis redis-cli -a mypassword ping
15# 应返回 PONG
说明:–appendonly yes 开启 AOF 持久化,重启后数据不丢失。redis:7-alpine 镜像体积仅约 45MB,适合资源受限环境。
场景 4:Python Flask / Node.js 应用开发调试
假设你正在开发一个 Python Flask 项目,目录结构如下:
1/home/user/myapp/
2├── app.py
3├── requirements.txt
4└── Dockerfile
开发阶段不需要每次都重新构建镜像,可以直接挂载代码目录:
1# 挂载代码目录,修改代码后容器内自动生效(配合 Flask 热重载)
2docker run -d \\
3 –name myapp \\
4 -p 5000:5000 \\
5 -v /home/user/myapp:/app \\
6 -w /app \\
7 python:3.12 \\
8 python app.py
说明:-w /app 设置工作目录。Flask 开启 debug=True 后,宿主机修改 app.py,容器内会自动重新加载,无需重启容器。Node.js 项目同理,挂载 src 目录配合 nodemon 即可实现热更新。
场景 5:多容器互联 — Web 应用 + MySQL
1# 创建自定义网络
2docker network create app-net
3
4# 启动 MySQL(加入 app-net 网络)
5docker run -d \\
6 –name mysql \\
7 –network app-net \\
8 -e MYSQL_ROOT_PASSWORD=123456 \\
9 -e MYSQL_DATABASE=mydb \\
10 -v mysql-data:/var/lib/mysql \\
11 mysql:8.0
12
13# 启动应用容器(加入同一网络,通过容器名访问数据库)
14docker run -d \\
15 –name myapp \\
16 –network app-net \\
17 -p 8080:8080 \\
18 -e DB_HOST=mysql \\
19 -e DB_PORT=3306 \\
20 -e DB_USER=root \\
21 -e DB_PASSWORD=123456 \\
22 -e DB_NAME=mydb \\
23 myapp:1.0
说明:同一自定义网络中的容器可以通过容器名直接解析 IP,无需硬编码数据库地址。应用代码中 DB_HOST 填写 mysql 即可连接到 MySQL 容器。

