Docker 操作手册

10 分钟
本页目录

先确认操作的是哪个 daemon、哪个 Compose 项目,再分清容器、镜像、卷和端口。以下示例名为 myapp,命令在 Docker 客户端执行;bind mount 路径属于 daemon 所在机器。

当前任务入口
容器退出或反复重启状态与日志
发布端口、持久化数据创建与路径
更新 Compose 服务配置到运行实例
磁盘占用大按对象清理

确认 daemon,再读容器状态

确认客户端连到哪里

# 读取当前选中的 context
docker context show

再用 docker context ls 对照 Endpoint。命令行 --context、环境变量 DOCKER_HOST / DOCKER_CONTEXT 也可能影响实际目标;docker info 能验证连接与 daemon 身份。连接失败先查地址、服务和权限。

定位容器及退出原因

# 包括已退出容器,列出名称、状态和端口
docker ps -a --format '{{.Names}}	{{.Status}}	{{.Ports}}'

-a 避免只看到运行实例;后续 myapp 替换为这里查到的名称。Exited 是进程已结束,Restarting 是正在重试,不能仅凭状态推断原因。

# 读取退出码、OOM 标记与健康检查状态
docker inspect myapp --format '{{json .State}}'

优先看 ExitCode、OOMKilled、Error、StartedAt / FinishedAt。若存在 Health,展开其中 Log 的探针输出;下表给出判断分支。

# 限定最近十分钟、最多一百行日志
docker logs --tail 100 --since 10m myapp

--tail 控制行数,--since 控制时间;持续观察另加 --follow,Ctrl-C 只结束跟随。日志来自容器标准输出/错误及其日志驱动,不保证包含应用自己写入文件的日志。

资源压力与进程是两种检查

# 取得一次 CPU、内存和 I/O 使用快照
docker stats --no-stream myapp

内存使用与限制一起看;短时峰值需要连续观察,单次低占用不能排除此前 OOM。

# 列出容器当前进程,核对应用是否启动
docker top myapp

这里回答进程存在与否,不代替日志或业务请求检查。

证据解释与下一步
ExitCode / Error先看应用退出日志;非零码不等于 Docker 自身故障
OOMKilled=true结合限制、宿主内存和内核日志检查;137 单独不能证明 OOM
unhealthy看 Health.Log 的探针;容器可能仍运行
Restarting先查应用为什么退出,再看 RestartPolicy;不要先加重启频率

把端口与数据的位置写清楚

创建网络与持久化卷

下面是一组新建示例,名称应尚未使用;已有对象先 inspect 核对再复用。创建失败先处理原因,不继续启动容器。

# 为应用建立独立的用户定义网络
docker network create app-net

成功输出网络 ID;同网络容器可按名称通信。

# 创建独立于容器生命周期的数据卷
docker volume create app-data

成功输出卷名;这一步只建立存储对象,不会替应用配置数据目录。

创建一个绑定回环端口的容器

# 使用前面确认的网络与卷创建实例
docker run -d --name myapp \
  --network app-net \
  --publish 127.0.0.1:8080:80 \
  --mount type=volume,src=app-data,dst=/app/data \
  --restart unless-stopped \
  --memory 512m \
  nginx:stable

-d 后台运行,--name 固定操作名称,--memory 限制内存,unless-stopped 控制退出后的重启策略。成功返回容器 ID;接着查 ps / logs 和下一节的端口、挂载,不能仅以 ID 判断应用健康。

这是创建语法示例:nginx 不会自动向 /app/data 写业务数据;实际应用必须把持久化路径配置到挂载点。换行反斜杠后不能再接注释。生产镜像按项目要求固定版本或 digest。

正在呈现知识画面
删除容器时,数据留在哪里

停止容器保留可写层;删除容器丢失可写层但保留普通命名卷。Compose down -v 还删除本项目的非 external 命名卷,镜像仍可存在。

对象操作含义
127.0.0.1:8080:80daemon 主机回环 8080 → 容器 80;其他容器应在自定义网络中访问服务名:80
--mount type=bind宿主路径映射;挂载会遮住镜像里目标目录原来的内容
--mount type=volumeDocker 管理的数据对象,生命周期独立于容器
EXPOSE镜像元数据,不自动发布宿主端口

验证端口与数据路径

# 核对实际发布到宿主的地址和端口
docker port myapp

应看到容器 80/tcp 映射到 127.0.0.1:8080。没有输出先查容器创建参数。

# 核对卷名、容器路径与读写属性
docker inspect myapp --format '{{json .Mounts}}'

查看 Type、Name、Destination 和 RW,确认应用实际写入该 Destination。挂载正确但应用写错目录,仍会丢失容器层里的数据。

# 确认网络归属、地址和别名
docker inspect myapp --format '{{json .NetworkSettings.Networks}}'

容器间访问应核对网络是否相同及应用监听地址。需要读容器 DNS 配置时,另用 docker exec myapp cat /etc/resolv.conf。

# 在 daemon 主机请求已发布的 HTTP 端口
curl -v http://127.0.0.1:8080/

看连接地址、HTTP 状态与响应正文;远程 context 时应登录 daemon 主机执行,而不是请求客户端自己的回环地址。

读取运行配置或进入容器

# 把容器内的配置复制到客户端供审阅
docker cp myapp:/etc/nginx/nginx.conf ./nginx.running.conf

源在容器、目标在客户端当前目录;目标文件名应未占用或已备份。复制不是热加载配置。交互诊断可另用 docker exec -it myapp sh;退出 shell 不停止主进程。

HTTP 请求中的 curl 要在 daemon 主机上验证;远程 context 下本机 localhost 不是 daemon。容器没有 shell 时 exec sh 会失败,可用 inspect、logs、cp 或适配其运行时的调试工具,不把缺少 shell 当成容器损坏。

重启不等于应用新配置

先确认 Compose 项目

在正确的 compose.yaml 所在目录执行;示例服务名 app 从 config 输出取得,不等于容器名 myapp。项目目录不同、-f / -p 不同,可能操作完全不同的一组对象。

# 检查配置是否能解析,避免输出展开后的配置
docker compose config --quiet

成功通常无输出;报错先修复文件或环境变量,不继续发布。

# 列出本次配置实际包含的服务
docker compose config --services

对照 docker compose ps -a 的已有实例,确认 app 是本次要更新的服务。

拉取、应用、检查是连续的发布阶段

# 取得 app 配置引用的镜像,不重建容器
docker compose pull app

拉取失败先处理认证、网络或镜像引用;成功后才执行 up。本地源码构建服务改用 docker compose build app,不是必须同时执行 pull 与 build。

# 依据当前配置创建或更新 app 及所需依赖
docker compose up -d app

会根据差异重建容器,需评估连接中断。只重启旧进程的 restart 不应用环境变量等容器配置变化。

# 检查新实例是否运行和通过健康检查
docker compose ps -a app

再用 docker compose logs --tail 100 app 与实际业务请求验证。失败时先保留日志,再恢复已记录的上一版镜像及配置并重新 up;数据迁移不会随镜像回退自动撤销。

在正确 Compose 文件目录执行,必要时显式 -f 和 -p 固定项目。restart 重启已有容器,不应用改过的环境变量;up -d 根据变更重建,构建源码项目才加 --build。config 的完整输出可能含已展开凭据,不应随意分享。

命令作用
docker stop -t 30 myapp按配置的停止信号请求退出,超时后强制结束
docker compose down删除项目容器及相应网络,默认不删除具名卷
docker compose down -v还删除受管理的具名卷和附属匿名卷;external 卷不由它删除

先定位占用,再清理具体对象

从占用清单选择对象

# 查看镜像、容器、卷和缓存的占用明细
docker system df -v

RECLAIMABLE 是引用规则下可回收的估计,不等于业务允许删除;共享层也使各项大小不能简单相加。

# 列出已退出容器,逐个确认是否仍需保留
docker container ls -a --filter status=exited

检查 logs、inspect、挂载与容器可写层需要的文件,再决定删除;停止状态不会自动保护其数据。

# 仅删除已确认不再需要的停止容器
docker rm myapp

此操作删除容器可写层,具名卷仍在。若容器运行,先按上表 stop 并确认业务停止,不直接加 -f。用 docker ps -a 确认对象消失。

# 确认准备处理的卷及其标签、挂载位置
docker volume inspect app-data

还需用 docker ps -a --filter volume=app-data 检查引用,并验证备份能恢复。确定销毁数据时才单独执行 docker volume rm app-data;“没有引用”不代表内容无价值。

镜像清理与镜像搬运分别处理

# 找到要审阅的镜像引用和大小
docker image ls

需要检查构建层时用 docker image history nginx:stable。确认不再需要后,以 docker image rm IMAGE 指定删除;IMAGE 从此列表取得,不用一键清空代替判断。

# 将镜像及其层导出为客户端归档
docker save nginx:stable -o nginx-image.tar

选择不会覆盖已有备份的输出路径。传输到目标机器后,才在目标 Docker 客户端执行下一步。

# 在目标 daemon 中导入归档镜像
docker load -i nginx-image.tar

核对输出标签与 docker image inspect nginx:stable 的镜像 ID。save/load 不包含卷数据、运行配置或容器当前可写层。

先确认哪些数据已备份、哪些停止容器仍需保留,再逐个 rm/rmi/volume rm。prune 按“未被引用”等规则判断,不知道业务价值;system prune -a --volumes 不作为日常一键修复。镜像 save/load 不备份卷;commit 也不包含挂载卷内容。

docker.sock 的管理权限通常相当于宿主高权限;不要为消除报错直接 chmod 666。网络异常先检查 daemon、防火墙后端和容器网络,"iptables": false 不是切换到 nftables 后端的方法。

Docker storage · Compose up · Docker nftables