Docker 常用基础指令可以分为几个类别:镜像管理、容器管理、网络与数据管理、Dockerfile 构建相关 等。以下是常用命令及简要说明,适合作为学习笔记或速查手册使用。
📦 镜像管理相关
| 命令 | 说明 |
|---|---|
docker images | 列出本地所有镜像 |
docker pull <镜像名> | 从远程仓库拉取镜像 |
docker rmi <镜像ID或名> | 删除镜像 |
docker build -t <镜像名:标签> . | 使用 Dockerfile 构建镜像 |
docker tag <镜像ID> <新标签> | 给镜像打标签 |
docker save -o xxx.tar <镜像名> | 将镜像保存为 tar 包 |
docker load -i xxx.tar | 从 tar 包加载镜像 |
🔍 docker images(完整形式:docker image ls)
-
作用:列出本地所有镜像。
-
别名:
docker image ls是正式写法,docker images是简写形式。 -
常用参数:
-a, --all:显示所有镜像(包含中间层镜像)--digests:显示镜像摘要(SHA256)--filter, -f:按照条件筛选(如 dangling=true)
-
示例:
docker images docker image ls -a docker image ls --filter "dangling=true"
⬇️ docker pull <镜像名>
-
作用:从远程镜像仓库(默认 Docker Hub)拉取镜像。
-
语法补充:
docker pull <镜像名>:<标签> -
示例:
docker pull nginx docker pull python:3.10-slim -
说明:
- 默认拉取
latest标签; - 如果镜像来自私有仓库,需登录后操作:
docker login
- 默认拉取
🗑️ docker rmi <镜像ID或名>(完整形式:docker image rm)
-
作用:删除本地镜像。
-
常用参数:
-f, --force:强制删除(即使镜像被容器使用)
-
示例:
docker rmi nginx docker image rm nginx:1.19 docker rmi -f 镜像ID -
注意事项: 删除前确保镜像未被任何容器引用(
docker ps -a查看)。
🛠️ docker build -t <镜像名:标签> .(完整形式:docker buildx build)
-
作用:根据当前目录下的
Dockerfile构建镜像。 -
推荐使用:
docker buildx build是新版多平台构建入口。 -
常用参数:
-t:指定镜像名称与标签-f:指定 Dockerfile 路径--platform:构建目标平台(如 linux/amd64, linux/arm64)--push:构建后直接推送镜像到远程仓库
-
示例:
docker build -t myapp:latest . docker buildx build --platform linux/amd64 -t myapp:v1 . -
建议: 本地简单构建使用
docker build即可,跨平台构建推荐使用docker buildx build。
🏷️ docker tag <源镜像> <新标签>
-
作用:给已存在的镜像打新标签(类似于重命名/版本号切换)
-
示例:
docker tag nginx myrepo/nginx:custom docker tag myapp:latest registry.example.com/myapp:1.0.1 -
说明: 打标签不会创建新的镜像副本,仅是指向同一个镜像 ID。
💾 docker save -o xxx.tar <镜像名>(完整形式:docker image save)
-
作用:将镜像导出为
.tar文件,便于离线传输或备份。 -
参数:
-o:输出文件路径
-
示例:
docker save -o nginx.tar nginx:1.21 -
说明: 可导出多镜像:
docker save -o apps.tar app1 app2
📂 docker load -i xxx.tar(完整形式:docker image load)
-
作用:从
.tar文件中加载镜像回 Docker 本地。 -
参数:
-i:指定输入文件
-
示例:
docker load -i nginx.tar -
说明: 加载后镜像会出现在
docker images中。
📦 容器管理相关
| 命令 | 说明 |
|---|---|
docker ps | 列出运行中的容器 |
docker ps -a | 列出所有容器(含停止) |
docker run <镜像> | 创建并运行一个容器 |
docker run -it <镜像> /bin/bash | 进入交互式终端容器 |
docker start <容器ID> | 启动容器 |
docker stop <容器ID> | 停止容器 |
docker restart <容器ID> | 重启容器 |
docker rm <容器ID> | 删除容器 |
docker exec -it <容器ID> bash | 在运行中容器内执行命令 |
docker logs <容器ID> | 查看容器日志 |
🚟 docker ps
说明 列出当前所有正在运行的容器。
别名/全名
docker container ls(官方推荐全名)
示例
docker ps
docker container ls
输出示例
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx:latest "nginx -g 'daemon of…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp webserver
ℹ️ docker ps -a
说明 列出所有容器,包括运行中和已停止的。
别名/全名
docker container ls -a
示例
docker ps -a
docker container ls -a
🚙 docker run <镜像>
说明 创建并启动一个新容器,基于指定的镜像,执行默认命令。
别名/全名
docker container run
示例
docker run ubuntu
此命令会拉取 ubuntu 镜像(若本地没有),创建容器并运行默认命令(一般是 bash 或 sh)。
👟 docker run -it <镜像> /bin/bash
说明 创建并启动一个容器,进入该容器的交互式终端(TTY),通常用于调试或手动操作。
参数说明
-i保持 STDIN 打开-t分配伪终端
示例
docker run -it ubuntu /bin/bash
运行后,会进入容器内的 bash 交互终端。
▶️ docker start <容器ID>
说明 启动已创建但当前处于停止状态的容器。
别名/全名
docker container start
示例
docker start a1b2c3d4e5f6
⏹️ docker stop <容器ID>
说明 优雅停止一个正在运行的容器,默认会发送 SIGTERM 信号,允许容器正常退出,超过默认时间后强制终止。
别名/全名
docker container stop
示例
docker stop a1b2c3d4e5f6
🔁 docker restart <容器ID>
说明
停止并立刻启动一个容器,相当于 stop 后紧接 start。
别名/全名
docker container restart
示例
docker restart a1b2c3d4e5f6
❌ docker rm <容器ID>
说明 删除一个已经停止的容器。若容器运行中需要先停止才能删除,或使用强制删除参数。
别名/全名
docker container rm
示例
docker rm a1b2c3d4e5f6
# 强制删除运行中容器(不推荐)
docker rm -f a1b2c3d4e5f6
🏃♂️➡️ docker exec -it <容器ID> bash
说明 在运行中的容器内执行命令,并且以交互终端方式进入。常用于进入容器调试或运行额外命令。
别名/全名
docker container exec
docker exec 深度解析:连接容器的不止是 Bash,还有更多场景
docker exec 允许我们在正在运行中的容器中执行命令,是日常调试、运维、日志查看、动态配置的强大工具。但这条命令的真正威力远不止“进入容器执行命令”这么简单。
一、基本用法:在运行容器中执行命令
docker exec -it mycontainer bash
-i:保持标准输入流(interactive)-t:分配伪终端(tty)mycontainer:容器名称或 IDbash:在容器中运行的命令
💡 说明:
-
如果容器内没有
bash(如 Alpine),你可以尝试:docker exec -it alpine-container sh
二、运维场景:动态调试 + 临时任务执行
✅ 查看容器内环境变量
docker exec myapp printenv
✅ 临时运行诊断工具
docker exec -it nginx curl -I http://localhost
✅ 拷贝、解压、生成数据
docker exec myapp tar -czf /data/backup.tar.gz /app/data
📌 注意:exec 执行的是当前容器上下文环境下的命令,不依赖宿主机。
三、结合用户身份与安全控制
docker exec -u 1001 myapp whoami
-u <UID|user>:指定用户运行命令,适合有多用户角色的服务容器。- 某些基础镜像(如
debian,ubuntu)会默认创建多个用户角色,可配合使用。
🚨 安全提示:
- 避免以 root 身份执行高风险命令(如
rm -rf /data),除非你清楚权限边界。 - 若容器内部已运行低权限服务,应保持一致的执行环境。
四、在 CI/CD 中批量执行命令
在 CI/CD 脚本中,docker exec 常被用于部署后配置、热更新、动态注册等操作:
docker exec webapp sed -i 's/debug=true/debug=false/' /app/conf/settings.ini
docker exec webapp systemctl reload nginx
📦 示例场景:
- 将容器内配置与外部环境同步
- 容器运行后加载 secrets 或注册到 Consul、etcd 等配置中心
五、与 docker run 的区别与边界
| 功能点 | docker run | docker exec |
|---|---|---|
| 作用对象 | 创建并启动新的容器 | 在已运行容器中执行命令 |
| 是否新建容器 | 是 | 否 |
| 应用场景 | 启动服务容器/临时任务容器 | 远程登录容器/动态运维 |
| 生命周期 | 命令完成后容器可能销毁 (--rm) | 不影响原容器运行状态 |
六、常见误区与性能注意
-
❌
docker exec执行后台命令并不会自动 detach,比如:docker exec myapp sleep 1000会阻塞执行,直到
sleep完成。 -
❌ 不能在未运行的容器中使用
docker exec:Error response from daemon: Container <id> is not running➜ 正确做法是先
docker start <id>,再exec。 -
❌ 不适合执行复杂任务(建议用
docker cp + bash script)
七、高级技巧与替代方案
✅ 使用 nsenter 与宿主机隔离交互
可选安装 nsenter 工具用于更底层方式进入容器(如进入 pause 容器),但一般不推荐。
✅ 通过 Entrypoint + signal 控制替代 exec
对于需要热重载配置的容器,不推荐频繁 exec,而应设计好 ENTRYPOINT 支持监听 SIGHUP 或 SIGUSR1 信号:
docker kill --signal=HUP myapp
这是一种更“优雅”的容器通信方式。
八、总结:docker exec 是容器中的 SSH,但别滥用
docker exec 是连接容器最直接的通道,也是最容易造成误操作的接口。合理使用可大幅提升运维效率,但不规范使用也可能绕过配置管理系统,制造技术债。
✅ 推荐使用场景:
- 临时调试、运维
- 动态查看或注入信息
- 脚本中批量任务执行
❌ 不推荐使用场景:
- 持续性任务(用 volume + CMD)
- 容器初始化配置(应在 Dockerfile 或 entrypoint 中完成)
📓 docker logs <容器ID>
说明 查看指定容器的标准输出日志。
别名/全名
docker container logs
示例
docker logs a1b2c3d4e5f6
# 监听日志实时输出
docker logs -f a1b2c3d4e5f6
🗂️ 网络与端口/数据卷
| 命令 | 说明 |
|---|---|
docker network ls | 查看网络列表 |
docker network create <网络名> | 创建自定义网络 |
docker volume ls | 查看所有数据卷 |
docker volume create <卷名> | 创建数据卷 |
docker run -v <本地路径>:<容器路径> <镜像> | 绑定挂载 |
docker inspect <容器/镜像> | 查看详细元信息 |
🛜 docker network ls
说明
- 列出本机上的所有 Docker 网络。包括内置(bridge、host、none)和用户自建网络。
别名/全名
- 官方全称:
docker network ls
示例
docker network ls
# 输出示例
# NETWORK ID NAME DRIVER SCOPE
# abcd1234efgh bridge bridge local
# ijkl5678mnop host host local
# qrst9012uvwx none null local
# yzab3456cdef network1 bridge local
🆕 docker network create
说明
- 创建一个自定义网络,支持多种驱动(bridge、overlay、macvlan 等),可指定子网、网关、IP 范围。
别名/全名
- 官方全称:
docker network create
常用参数示例
# 创建一个默认 bridge 网络,名称 network1
docker network create network1
# 指定子网与网关
docker network create \
--driver bridge \
--subnet 172.18.0.0/16 \
--gateway 172.18.0.1 \
network2
# 创建 overlay 网络(用于 Swarm 集群)
docker network create \
--driver overlay \
--attachable \
swarm-net
📜 docker volume ls
说明
- 列出本机上所有 Docker 卷(volume),包括挂载状态和驱动类型。
别名/全名
- 官方全称:
docker volume ls
示例
docker volume ls
# 输出示例
# DRIVER VOLUME NAME
# local mydata
# local db_volume
🗞️ docker volume create
说明
- 创建一个新的 Docker 卷,可指定驱动和驱动选项,用于持久化容器数据。
别名/全名
- 官方全称:
docker volume create
常用参数示例
# 创建一个默认 local 驱动的卷
docker volume create mydata
# 使用自定义驱动及选项(例如 rexray)
docker volume create \
--driver rexray \
--opt size=10 \
--opt encrypted=true \
secure_vol
# 创建带标签(label)的卷
docker volume create \
--label project=demo \
--label env=prod \
labeled_vol
✉️ docker inspect
说明
- 输出低层次的对象(容器、镜像、网络、卷等)详细 JSON 信息,包括配置、状态、网络设置、挂载点等。
- 可结合
-f(format) 参数使用 Go 模板过滤输出字段。
别名/全名
- 官方全称:
docker inspect
常用参数示例
# 查看容器详细信息
docker inspect mycontainer
# 只查看某个字段,如容器的 IP 地址
docker inspect -f '{{ .NetworkSettings.IPAddress }}' mycontainer
# 查看网络详细信息
docker inspect network1
# 查看卷挂载信息
docker inspect mydata
🏃♂️ docker run
说明
- 拉取(若本地无镜像)并创建一个新容器,执行镜像默认命令,然后退出或持续运行。
- 可通过各种参数控制网络、挂载卷、环境变量等。
别名/全名
- 官方全称
docker container run
docker run 命令深度解析:不仅仅是启动一个容器
docker run 是 Docker 使用频率最高的命令之一,但它同时也是最“复杂”的命令之一。大多数初学者只用它来“跑一个镜像”,但在实际生产中,我们更关注的是:
- 容器如何命名与管理?
- 是否具备正确的数据持久化策略(卷挂载)?
- 网络是否暴露在安全范围内(端口映射)?
- 是否通过环境变量传递了敏感配置?
- 容器是否最小权限运行?
下面我们从这些维度逐一深入解析。
一、容器命名与生命周期控制
docker run --name myapp --rm nginx
--name myapp:为容器设置可读性强的名称,便于后续使用docker start myapp管理容器。--rm:容器退出后自动删除,适合一次性任务;注意不适用于持久服务。
🔍 生产推荐:
- 后台服务容器不建议
--rm,避免数据丢失。 - 命名采用结构化格式,如:
appname-env-role-1
二、端口映射与安全边界
docker run -d -p 8080:80 nginx
-p 主机端口:容器端口:映射容器端口到宿主机,访问服务变得可能。-P:自动分配所有EXPOSE的端口,不推荐用于生产,不可控。
🔐 安全提示:
- 只映射必要端口,最好加
--network bridge限制暴露范围。 - 不建议直接暴露数据库端口(如
3306,6379),应通过网关或 VPN 限制访问。
三、数据卷挂载与持久化
docker run -v /data/nginx/html:/usr/share/nginx/html nginx
-v <宿主路径>:<容器路径>:绑定挂载(bind mount),适合开发调试。-v myvolume:/data:使用命名卷,Docker 自动管理,适合生产持久化。
📦 示例:挂载配置目录与日志目录
docker run \
-v /etc/myapp/conf:/app/conf \
-v myapp_logs:/var/log/myapp \
myapp:latest
🧱 推荐策略:
- 配置用 bind mount,便于热更新;
- 日志与数据目录使用 volume,便于备份与迁移。
四、环境变量与敏感信息注入
docker run -e MYSQL_ROOT_PASSWORD=secret mysql
-e设置环境变量,是配置密码、用户名等的标准方式。
🌱 安全建议:
-
不将密码写死在命令中;可用
.env文件配合--env-file使用:docker run --env-file ./myenv.list myapp -
敏感信息也可以结合
docker secret(Swarm)或Kubernetes Secret管理。
五、用户权限控制与最小权限原则
docker run -u 1001:1001 myapp
-u <UID>:<GID>:以指定的非 root 用户运行容器,避免容器被入侵后获取宿主机 root 权限。
🔐 安全建议:
- 永远不要在生产环境以 root 用户运行容器,除非必须。
- 最好自定义镜像时已切换到非 root 用户(
USER指令)。
六、综合实例:一个“生产级”运行命令
docker run -d \
--name webapp-prod \
-p 443:443 \
-v /etc/webapp/conf:/app/conf:ro \
-v webapp_data:/app/data \
--env-file ./secrets.env \
--restart=always \
--user 1001:1001 \
myorg/webapp:1.0.2
功能说明:
| 功能 | 参数 |
|---|---|
| 服务端口映射 | -p 443:443 |
| 配置文件挂载(只读) | -v ...:ro |
| 数据卷持久化 | -v webapp_data:... |
| 环境变量注入 | --env-file |
| 非 root 运行 | --user |
| 自动重启策略 | --restart=always |
七、总结:docker run 是“镜像->服务”的桥梁
一个优秀的 docker run 命令,不仅仅能“跑起来”,更要具备以下特性:
- 命名规范:便于管理;
- 卷挂载清晰:数据安全;
- 网络控制:接口收敛;
- 权限配置:最小授权;
- 配置解耦:环境变量注入;
- 自动恢复:加上
--restart策略。
真正用好 docker run,就能构建起一个“结构化、可控、安全”的容器服务基础架构。
🛠️ Dockerfile 构建相关命令回顾
Dockerfile 是构建 Docker 镜像的脚本文件,定义了镜像内应该包含的内容和构建步骤。掌握它,就等于掌握了容器化应用的核心生产力工具。
参考文档
🧱 Dockerfile 是什么?
Dockerfile 是一个文本文件,包含了一系列用于构建镜像的指令(Instructions)。这些指令会被 docker build 命令顺序执行,最终生成一个可运行的容器镜像。
🧩 Dockerfile 核心指令全览
一个标准的 Dockerfile 通常包括以下几个核心部分:
| 指令 | 作用 |
|---|---|
FROM | 指定基础镜像(如 ubuntu, alpine, python) |
RUN | 在构建镜像时运行命令(如安装依赖) |
COPY / ADD | 将本地文件复制到镜像中 |
WORKDIR | 设置工作目录 |
CMD / ENTRYPOINT | 设置容器启动时执行的命令 |
EXPOSE | 声明容器监听的端口(文档用途) |
ENV | 设置环境变量 |
ARG | 定义构建时变量 |
VOLUME | 定义挂载卷位置(持久化数据) |
LABEL | 添加元数据信息(如作者、版本) |
以下是构建镜像最常用的 Dockerfile 指令:
1. FROM(基础镜像)
定义构建镜像所基于的父镜像。必须是第一条非注释指令。
FROM node:20-alpine
2. RUN(执行命令)
在镜像构建时执行 shell 命令,常用于安装依赖、修改配置。
RUN apk add --no-cache python3
3. COPY / ADD(复制文件)
将宿主机上的文件复制到镜像中。
COPY:基础复制ADD:支持远程 URL、自动解压 tar 文件
COPY . /app
ADD https://example.com/data.tar.gz /data/
4. WORKDIR(设置工作目录)
设置后续指令的默认工作路径。
WORKDIR /app
5. CMD / ENTRYPOINT(定义启动命令)
CMD:容器默认启动命令,可被覆盖ENTRYPOINT:更强制的启动命令(不容易被替换)
CMD ["node", "index.js"]
ENTRYPOINT ["python3", "main.py"]
🔎 CMD vs ENTRYPOINT 有啥区别?
| 项目 | CMD | ENTRYPOINT |
|---|---|---|
| 默认命令 | ✅ | ✅ |
可被 docker run 覆盖 | ✅ | ❌(除非加 --entrypoint) |
| 最常用途 | 提供默认命令参数 | 设置主命令(如 nginx) |
结合使用:
ENTRYPOINT ["python"]
CMD ["app.py"]
6. EXPOSE(声明端口)
声明容器运行时监听的端口(仅声明,不会自动映射主机端口)。
EXPOSE 8080
7. ENV(设置环境变量)
ENV NODE_ENV=production
8. ARG(构建参数)
在构建阶段可传递变量,通常与 --build-arg 配合使用。
ARG VERSION=1.0
RUN echo "Build version: $VERSION"
🧠 Dockerfile 编写建议
-
选择轻量镜像:如
alpine,减小体积、提升构建速度。 -
减少层数:将多个
RUN命令合并。RUN apt update && apt install -y curl && rm -rf /var/lib/apt/lists/* -
使用
.dockerignore:避免将无关文件复制进镜像。 -
固定版本号:确保构建的可重复性。
-
使用
ENTRYPOINT+CMD组合:提高灵活性。 -
利用缓存优化构建顺序:常变的文件放后面。
-
多阶段构建(Multi-stage build): 只保留运行时必要内容,精简镜像体积。
🧪 示例:打包一个 Python Flask 应用
# 使用官方 Python 基础镜像
FROM python:3.10-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install -r requirements.txt
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 5000
# 启动应用
CMD ["python", "app.py"]
构建镜像:
docker build -t flask-demo .
运行容器:
docker run -p 5000:5000 flask-demo
🚫 常见坑点
COPY顺序错 → 构建缓存失效RUN安装完没清理缓存 → 镜像超大WORKDIR未设置 → 程序路径混乱EXPOSE没映射 → 容器内部服务无法访问ENTRYPOINT写死 → 无法调试或扩展
🚀 总结
Dockerfile 是构建镜像的描述性语言,掌握它可以:
- 标准化部署流程
- 避免“在我电脑上可以跑”
- 与 CI/CD 高效集成
🧹 系统清理与管理
| 命令 | 说明 |
|---|---|
docker system df | 查看资源占用 |
docker system prune | 清理未使用的资源(危险操作) |
docker image prune | 清理未使用的镜像 |
docker container prune | 清理已停止的容器 |
docker volume prune | 清理无用的卷 |
⚙️ docker system df
说明 显示 Docker 守护进程当前各类对象(镜像、容器、本地卷、构建缓存等)所占用的磁盘空间总量和可回收量。网络信息不在此统计中,因为其并不占用磁盘空间。
常用选项
-v, --verbose:显示更详细的使用情况,包括每个镜像、容器和卷的具体大小。
示例
# 仅显示概要
docker system df
# 显示详细信息
docker system df --verbose
🧹 docker system prune
说明 一次性移除所有未被使用的容器、网络、(悬挂和未被任何容器引用的)镜像,以及可选地移除未使用的卷。属于危险操作,执行前会有确认提示。
常用选项
-a, --all:除了移除“悬挂”镜像,也移除所有未被任何容器使用的镜像。--volumes:同时移除所有未被任何容器使用的卷。-f, --force:跳过确认提示,直接执行。--filter <表达式>:根据条件过滤要移除的对象(如until=24h表示仅移除 24 小时前未使用的资源)。
示例
# 移除悬挂镜像、停止容器、未用网络及构建缓存
docker system prune
# 加上 -a,移除所有未被容器使用的镜像
docker system prune --all
# 同时移除未使用的卷
docker system prune --volumes
# 跳过确认
docker system prune --force
# 仅移除 48 小时前未使用的资源
docker system prune --filter "until=48h"
📀 docker image prune
说明
清理“悬挂”(dangling)镜像:即没有标签且未被任何容器引用的镜像。加上 -a 则移除所有未被任何容器使用的镜像。
常用选项
-a, --all:移除所有未被容器使用的镜像,而不仅限于悬挂镜像。-f, --force:跳过确认提示。--filter <表达式>:例如until=24h仅移除 24 小时前创建的镜像。
示例
# 移除悬挂镜像
docker image prune
# 移除所有未被使用的镜像
docker image prune --all
# 跳过确认
docker image prune --force
# 仅移除 24 小时前的镜像
docker image prune --all --filter "until=24h"
🫙 docker container prune
说明 清理所有已停止的容器。已停止容器的可写层会继续占用磁盘空间,使用此命令可统一释放。
常用选项
-f, --force:无确认直接执行。--filter <表达式>:如until=24h仅移除 24 小时前停止的容器。
示例
# 移除所有已停止的容器
docker container prune
# 跳过确认
docker container prune --force
# 仅移除 48 小时前停止的容器
docker container prune --filter "until=48h"
🗂️ docker volume prune
说明 清理所有未被任何容器使用的卷。因卷可能包含重要数据,默认会提示确认,且需谨慎操作。
常用选项
-f, --force:无确认直接执行。--filter <表达式>:如label!=keep仅保留带有keep标签的卷。
示例
# 移除所有未使用的卷
docker volume prune
# 跳过确认
docker volume prune --force
# 仅移除未标记为 keep 的卷
docker volume prune --filter "label!=keep"
Docker 容器系统清理机制深入剖析
在容器开发与持续集成的日常实践中,磁盘空间的异常膨胀往往源自未管理的镜像、悬挂卷或停止的容器。这时,Docker 的一组 “prune” 系列命令便成为 DevOps 工程师清理系统资源的“清道夫”。然而,很多用户在使用这些命令时存在误解:prune 是“万能清理剂”吗?是否安全?为什么执行后镜像丢了?本文将从工作原理、使用边界、典型用例三方面进行深入分析。
1. docker system prune 背后的机制
docker system prune 并非简单地“强删”资源,而是 Docker 守护进程根据资源依赖关系和使用状态,递归扫描无引用资源的对象图,判断哪些资源已经“脱钩”,并进行删除。
它默认移除以下内容:
- 已停止的容器(
Exited状态) - 未使用的网络
- dangling 镜像(无 tag 且无容器引用的中间层镜像)
- 构建缓存(Docker BuildKit 所产生的中间产物)
使用 --volumes 时才会加入 无挂载的匿名卷(docker volume create 创建却未绑定容器的卷)。
📌 深度机制点:
docker system prune --volumes
相当于调用了:
docker container prune &&
docker image prune &&
docker network prune &&
docker volume prune
这意味着,system prune 是其他子命令的聚合调用,可通过组合参数决定“波及范围”。
2. 风险评估与安全边界
许多初学者在执行 docker system prune -a --volumes 后懊悔不已,因为发现自己常用的镜像和数据卷都被删除了。
关键点解释:
-a会删除所有未被容器使用的镜像,不区分是否有 tag。--volumes会删除所有未挂载的卷,包括数据卷,可能导致持久数据丢失。- 删除是不可恢复的,Docker 不提供回收站机制。
🔐 最佳实践:
-
使用
--filter加时间戳限制:docker system prune --filter "until=72h" -
针对镜像和数据卷,使用 label 管理保留策略:
docker volume prune --filter "label!=keep"
3. CI/CD 场景的优化用法
在 GitLab CI 或 GitHub Actions 中,Docker 层的持续构建会堆积大量 dangling 镜像和 build cache。如果不清理,Runner 容器可能在短时间内耗尽磁盘。
一个推荐做法是在每次构建前后使用定制化清理:
docker builder prune -f --filter "until=24h"
docker image prune -a -f --filter "until=24h"
这样可以定期清理 24 小时前的构建缓存与临时镜像,保留近期产物,提高构建速度并释放磁盘空间。
4. 总结:系统不是越干净越好,而是越“可控”越好
Docker 提供了强大且细粒度的资源清理命令,不同 prune 子命令各司其职。正确理解它们之间的范围区别与执行优先级,配合标签与时间过滤器,就可以构建出一个可预测、可恢复、可优化的容器资源生命周期体系。