Docker 系统越来越慢?可能是这些垃圾没清干净!
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
在使用 Docker 进行开发和部署时,随着时间的推移,系统中会积累大量的未使用或“悬挂”(dangling)的镜像(Images)、容器(Containers)、数据卷(Volumes)和网络(Networks)。这些残留资源不仅会占用宝贵的磁盘空间,还可能导致混淆或潜在的冲突。本指南将详细介绍如何利用 Docker 提供的命令来高效清理和管理您的 Docker 环境,确保系统保持整洁和最佳运行状态。 一键清理 Docker 资源Docker 提供了一个强大的命令 要清理所有未使用的或悬挂的镜像、容器、数据卷和网络,可以使用以下命令:
执行此命令时,系统会提示您确认操作,因为它会删除:
如果您希望进一步清理,包括删除所有已停止的容器和所有未使用的镜像(不仅仅是悬挂镜像),可以添加
此命令会删除所有已停止的容器和所有未被任何容器使用的镜像(包括悬挂镜像和未使用但有标签的镜像),但不会删除数据卷。如果需要清理数据卷,请继续阅读。 删除 Docker 镜像 (Images)镜像(Image)是构建容器的基础。随着项目迭代或测试,可能会留下许多无用的镜像层或完整镜像。 删除一个或多个特定镜像首先,使用 列出所有镜像:
删除特定镜像:
注意:
删除悬挂的 Docker 镜像悬挂镜像(Dangling Images)是指那些没有被任何标签引用,但其父层可能仍被其他标记镜像引用的镜像层。它们通常是由于镜像构建失败或新版本镜像覆盖旧版本后留下的。 列出悬挂镜像:
删除悬挂镜像:
此命令会自动查找并删除所有悬挂的镜像。 根据模式删除镜像如果您需要删除符合特定命名模式的镜像,可以结合使用 列出符合模式的镜像:
例如,查找所有名称中包含 "old_project" 的镜像。 删除符合模式的镜像:
此命令首先列出所有镜像,然后通过 删除所有镜像有时,为了彻底清理或从头开始,您可能需要删除本地所有的 Docker 镜像。 列出所有镜像的 ID:
删除所有镜像:
此命令会获取所有镜像的 ID,然后将它们作为参数传递给 删除 Docker 容器 (Containers)容器(Container)是 Docker 应用程序的运行实例。停止的容器虽然不再消耗 CPU 和内存,但仍会占用磁盘空间。 删除一个或多个特定容器首先,使用 列出所有容器:
删除特定容器:
退出时自动删除容器在创建容器时,可以通过添加 运行并自动删除:
删除所有已停止的容器已停止的容器通常是清理的首要目标,因为它们不会再被使用。 列出所有已停止的容器:
删除所有已停止的容器:
使用多个过滤器删除容器
列出符合多个过滤条件的容器:
删除符合多个过滤条件的容器:
根据模式删除容器与删除镜像类似,您也可以根据容器名称或镜像名称模式来删除容器。 列出符合模式的容器:
删除符合模式的容器:
停止并删除所有容器如果需要彻底清理,可以停止并删除所有正在运行和已停止的容器。 列出所有容器:
停止并删除所有容器:
警告: 这会停止并删除您所有的 Docker 容器,请谨慎操作。 删除 Docker 数据卷 (Volumes)数据卷(Volume)是 Docker 持久化数据的方式,它们独立于容器的生命周期。即使容器被删除,其关联的数据卷可能仍然存在,占用磁盘空间。 删除一个或多个特定数据卷首先,使用 列出所有数据卷:
删除特定数据卷:
删除悬挂数据卷悬挂数据卷(Dangling Volumes)是指那些存在但未连接到任何容器的数据卷。 列出悬挂数据卷:
删除悬挂数据卷:
此命令会自动查找并删除所有悬挂的数据卷。 删除容器及其数据卷如果容器使用了未命名(匿名)数据卷,可以在删除容器时,使用 删除容器并删除其匿名数据卷:
注意: 此命令仅删除未命名的数据卷。命名数据卷(Named Volumes)不会被删除,需要手动使用
|
docker rm | -f -v 删除匿名数据卷 | ||
docker rmi | -f | ||
docker prune | -a -f 强制删除 |
在使用 Docker 过程中,可能会遇到一些与清理相关的常见问题。
当多个容器尝试同时写入同一个数据卷时,可能会发生线程同步问题,导致数据损坏或不可预测的行为。
version: '3.8'
services:
app:
image: myapp
volumes:
- myvolume:/app/node_modules # 多个服务可以引用同一个命名数据卷
another_app:
image: another_app_image
volumes:
- myvolume:/data/shared
volumes:
myvolume: # 定义命名数据卷
flock
、lockfile
或编程语言提供的互斥锁(Mutex)机制,确保每次只有一个容器访问共享文件。depends_on
等机制可以控制服务启动顺序,但并不能直接解决数据卷写入的并发问题,仍需结合文件锁或设计数据访问模式。version: '3.8'
services:
app:
image: myapp
volumes:
- myvolume:/app/data
depends_on: # 确保 db 服务启动后 app 再启动,但这不解决并发写入问题
- db
db:
image: mydb
volumes:
- myvolume:/var/lib/mysql
volumes:
myvolume:
对于共享数据卷,核心在于应用程序层面的并发控制。
Docker 镜像由多个层(Layers)组成,过多的层可能导致镜像臃肿、构建速度慢、部署效率低。
docker history <image>
命令检查镜像的构建历史和每一层的大小,识别不必要的层。docker history myapp
RUN
指令合并为一个,减少生成的层数。例如,将多个 apt install
合并。# 不推荐:多条 RUN 指令会产生多层
# RUN apt update
# RUN apt install -y python3
# RUN apt install -y python3-pip
# 推荐:合并 RUN 指令以减少层数
RUN apt update && apt install -y python3 python3-pip
# 第一阶段:构建器 (builder)
FROM golang:1.20 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .
# 第二阶段:最终运行时镜像
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp . # 只复制构建好的可执行文件
CMD ["./myapp"]
container is running
错误当尝试使用 docker rm
命令删除一个正在运行的容器时,Docker 会报错提示 container is running
。
docker stop <container_id_或_name>
docker rm <container_id_或_name>
-f
或 --force
标志。这会强制终止容器并删除它,可能导致数据丢失或不完整。docker rm -f <container_id_或_name>
docker stop $(docker ps -a -q) # 停止所有容器
docker rm $(docker ps -a -q) # 删除所有容器
docker-compose down
命令可以停止并移除 Compose 文件中定义的所有服务、网络和匿名数据卷。docker-compose down
docker-compose down
docker system prune -a
docker system prune
会发生什么?-a
标志,还会删除所有未使用的镜像(包括悬挂镜像和无用的带标签镜像)。-f
标志强制删除:docker rm -f <container_id>
。docker system prune -a
:删除所有已停止容器和所有未使用镜像。docker system prune --all --volumes
:删除所有已停止容器、所有未使用镜像、所有未使用的网络和所有数据卷。此命令会清除与 Docker 相关的大部分数据,请谨慎使用。docker volume prune
:删除所有悬挂数据卷。docker network prune
:删除所有未使用的网络。docker rm
和 docker rmi
的区别是什么?docker rm
用于删除容器实例,不删除其基于的镜像。docker rmi
用于删除 Docker 镜像,前提是没有容器正在使用该镜像。docker rmi <image-id>
。如果该镜像正在被容器使用,需先停止并删除相关容器,或使用 -f
强制删除(不推荐)。docker image prune
:删除悬挂镜像。docker image prune --all
:删除所有未使用(包括悬挂和有标签但未使用的)镜像。docker system prune --all --volumes
。警告:此命令将删除与 Docker 相关的所有内容,包括镜像、容器、数据卷和网络。docker run -it <image-id> /bin/bash # 进入容器
# 在容器内执行删除文件操作,例如:rm /path/to/file
exit
docker commit <container-id> <new-image-name> # 提交为新镜像
docker container prune
或 docker rm $(docker ps -a -f status=exited -q)
。docker container prune -f
可以跳过确认提示。exited
(已退出)或 created
(已创建但未运行)状态的容器:docker ps -a --filter "status=exited" --filter "status=created" # 查看
docker rm $(docker ps -a -q --filter "status=exited" --filter "status=created") # 删除
/var/lib/docker
目录下。C:\ProgramData\DockerDesktop
。docker info | grep "Docker Root Dir"
命令来验证实际的存储路径。--rm
标志,使其在退出时自动删除:docker run --rm <image-id>
掌握 Docker 资源的清理和管理对于维护一个高效、整洁的开发和生产环境至关重要。本文详细介绍了如何使用 docker system prune
、docker rmi
、docker rm
和 docker volume rm
等命令来删除不需要的镜像、容器和数据卷。通过定期清理,您可以有效释放磁盘空间,避免潜在的冲突,并优化 Docker 的性能。建议定期执行清理操作,并查阅 Docker 官方文档以获取最新的命令用法和最佳实践。
阅读原文:原文链接