1. 问题背景与现状分析
最近在Ubuntu服务器上运行Docker时遇到了磁盘空间不足的问题,通过docker system df命令查看发现存储占用异常高。具体表现为:
code复制TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 34 11 56.56GB 23.17GB (40%)
Containers 11 5 101.5MB 88.38MB (87%)
Local Volumes 15 7 320.4MB 42.08MB (13%)
Build Cache 213 0 27.06GB 27.06GB
进一步检查发现,一个名为ragflow的容器套件(包含ragflow-server、Elasticsearch、MySQL和MinIO四个组件)已经运行了17个月,占用了大量空间。其中仅ragflow-server镜像就达到约19GB,是整个系统中最大的空间占用者。
2. 清理前的准备工作
2.1 确认要清理的组件
首先需要明确要清理的对象及其依赖关系。通过docker ps命令的输出可以看到ragflow相关容器:
code复制CONTAINER ID IMAGE NAMES
de3e37510785 swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev ragflow-server
bd7074df6dd9 docker.elastic.co/elasticsearch/elasticsearch:8.11.3 ragflow-es-01
3d8ba512967e mysql:5.7.18 ragflow-mysql
888e483fc702 quay.io/minio/minio:RELEASE.2023-12-20T01-00-02Z ragflow-minio
这些组件构成了一个完整的ragflow应用栈:
- ragflow-server:主服务容器
- Elasticsearch:用于搜索和索引
- MySQL:关系型数据库存储
- MinIO:对象存储服务
2.2 评估清理影响
在开始清理前,必须确认:
- 这些服务是否已经不再使用
- 是否需要保留其中的数据
- 清理是否会影响其他正在运行的服务(如输出中显示的gitlab容器)
通过检查确认这些ragflow组件可以安全移除,且不需要保留数据。
3. 分步清理过程
3.1 停止相关容器
首先停止所有ragflow相关容器,确保服务不再运行:
bash复制docker stop ragflow-server ragflow-es-01 ragflow-mysql ragflow-minio
停止后验证:
bash复制docker ps
应该只看到其他仍在运行的容器(如gitlab)。
3.2 删除容器实例
容器停止后,可以安全删除容器实例:
bash复制docker rm ragflow-server ragflow-es-01 ragflow-mysql ragflow-minio
删除后再次验证:
bash复制docker ps -a | grep ragflow
应该没有任何输出,表示容器已完全移除。
3.3 删除镜像文件
容器删除后,相关的镜像文件仍然占用磁盘空间。需要依次删除:
- 删除主ragflow镜像(最大空间占用):
bash复制docker rmi swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev
- 删除依赖的组件镜像:
bash复制docker rmi \
docker.elastic.co/elasticsearch/elasticsearch:8.11.3 \
mysql:5.7.18 \
quay.io/minio/minio:RELEASE.2023-12-20T01-00-02Z
删除后检查镜像列表:
bash复制docker images | grep -E "infiniflow/ragflow|elasticsearch|mysql|minio"
应该看不到相关镜像。
3.4 清理数据卷
容器和镜像删除后,相关的数据卷仍然存在。首先列出所有卷:
bash复制docker volume ls
输出示例:
code复制DRIVER VOLUME NAME
local docker_esdata01
local docker_minio_data
local docker_mysql_data
...
确认这些卷不再被使用后,可以删除:
bash复制docker volume rm docker_esdata01 docker_minio_data docker_mysql_data
如果担心误删,可以先确认卷是否被使用:
bash复制docker ps -a --filter volume=docker_esdata01
docker ps -a --filter volume=docker_minio_data
docker ps -a --filter volume=docker_mysql_data
3.5 清理残余容器和系统缓存
最后执行系统级清理,移除所有已停止的容器和构建缓存:
bash复制docker container prune -f
docker system prune -f
docker builder prune -f
docker image prune -f
4. 清理效果验证
清理完成后,检查系统状态:
bash复制docker system df
输出示例:
code复制TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 30 1 35.68GB 32.64GB (91%)
Containers 1 1 5.725MB 0B (0%)
Local Volumes 15 0 307.8MB 307.8MB (100%)
Build Cache 213 0 27.06GB 27.06GB
可以看到存储占用明显下降。再检查磁盘空间:
bash复制df -h
应该能看到根分区使用率显著降低。
5. 注意事项与经验分享
5.1 关键注意事项
- 顺序很重要:必须按照停止→删除容器→删除镜像→删除卷的顺序操作,否则可能出现依赖问题
- 数据备份:如果卷中有重要数据,应在删除前备份:
bash复制docker run --rm -v docker_mysql_data:/source -v $(pwd):/backup alpine tar czf /backup/mysql_backup.tar.gz -C /source .
- 依赖检查:删除镜像前确保没有其他容器依赖它
- 批量操作风险:批量删除命令(如
docker rmi多个镜像)如果中间出错会导致后续操作中断
5.2 实用技巧
- 空间分析:使用
docker system df -v查看详细的空间占用情况 - 按需清理:可以只清理特定类型的资源:
bash复制docker image prune -a --filter "until=24h" # 清理24小时前的镜像 docker volume prune --filter "label!=keep" # 清理无keep标签的卷 - 预防措施:定期清理可以避免空间不足:
bash复制# 每周自动清理 0 3 * * 0 docker system prune -f
5.3 常见问题解决
问题1:删除镜像时提示"image is referenced in multiple repositories"
解决:先删除其中一个仓库的引用:
bash复制docker rmi repository1/image:tag
问题2:卷删除失败,提示"volume is in use"
解决:找出使用该卷的容器并先删除容器:
bash复制docker ps -a --filter volume=volume_name
问题3:空间未按预期释放
解决:检查是否还有其他大文件或日志占用空间:
bash复制du -sh /var/lib/docker/*
journalctl --disk-usage
6. 后续维护建议
- 监控设置:配置监控告警,当Docker存储使用超过80%时通知
- 存储驱动优化:考虑使用更适合的存储驱动(如overlay2)
- 定期维护:将Docker清理加入常规维护任务
- 日志管理:配置日志轮转,避免日志文件无限增长
通过这次完整的清理过程,不仅解决了当前的磁盘空间问题,也为后续的Docker资源管理建立了规范的流程。记住,预防胜于治疗,定期维护比紧急清理更有效。