163 lines
4.5 KiB
Bash
163 lines
4.5 KiB
Bash
#!/bin/bash
|
|
|
|
# Docker Disk Cleanup Script
|
|
# Description: 清理Docker无用资源,释放磁盘空间
|
|
# Author: Your Name
|
|
# Date: $(date +%Y-%m-%d)
|
|
|
|
set -euo pipefail # 更安全的执行模式:遇到错误退出,未定义变量报错
|
|
|
|
# 配置变量 - 可根据需要调整
|
|
DRY_RUN=false # 设置为 true 时只显示将要执行的操作,而不实际执行
|
|
CLEAN_UNUSED_IMAGES=true # 清理未被使用的镜像
|
|
CLEAN_DANGLING_IMAGES=true # 清理悬空镜像(无标签且未被使用)
|
|
CLEAN_EXITED_CONTAINERS=true # 清理已退出的容器
|
|
CLEAN_BUILD_CACHE=true # 清理构建缓存
|
|
CLEAN_DANGLING_VOLUMES=false # 清理悬空卷(警告:这可能删除重要数据!)
|
|
CLEAN_UNUSED_NETWORKS=true # 清理未使用的网络
|
|
|
|
# 日志函数
|
|
log() {
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
|
}
|
|
|
|
# 危险操作确认函数
|
|
confirm_action() {
|
|
if [ "$DRY_RUN" = true ]; then
|
|
log "干运行模式:将执行 '$1'"
|
|
return 0
|
|
fi
|
|
|
|
log "执行: $1"
|
|
return 0
|
|
}
|
|
|
|
# 主清理函数
|
|
clean_docker() {
|
|
log "开始 Docker 磁盘清理..."
|
|
log "当前 Docker 磁盘使用情况:"
|
|
docker system df
|
|
|
|
# 清理已退出的容器
|
|
if [ "$CLEAN_EXITED_CONTAINERS" = true ]; then
|
|
log "查找已退出的容器..."
|
|
exited_containers=$(docker ps -aq -f status=exited)
|
|
if [ -n "$exited_containers" ]; then
|
|
log "找到已退出的容器: $exited_containers"
|
|
confirm_action "docker rm $exited_containers" && \
|
|
docker rm $exited_containers 2>/dev/null || \
|
|
log "警告: 删除某些容器时出错(可能正在使用中)"
|
|
else
|
|
log "未找到已退出的容器"
|
|
fi
|
|
fi
|
|
|
|
# 清理悬空镜像
|
|
if [ "$CLEAN_DANGLING_IMAGES" = true ]; then
|
|
log "清理悬空镜像..."
|
|
confirm_action "docker image prune -f" && \
|
|
docker image prune -f
|
|
fi
|
|
|
|
# 清理未使用的镜像
|
|
if [ "$CLEAN_UNUSED_IMAGES" = true ]; then
|
|
log "清理未被使用的镜像..."
|
|
unused_images=$(docker images -q --filter "dangling=false")
|
|
if [ -n "$unused_images" ]; then
|
|
log "找到未使用的镜像,建议手动检查后再删除"
|
|
# 更安全的做法是手动确认,这里只做提示
|
|
fi
|
|
fi
|
|
|
|
# 清理构建缓存
|
|
if [ "$CLEAN_BUILD_CACHE" = true ]; then
|
|
log "清理构建缓存..."
|
|
confirm_action "docker builder prune -f" && \
|
|
docker builder prune -f
|
|
fi
|
|
|
|
# 清理未使用的网络
|
|
if [ "$CLEAN_UNUSED_NETWORKS" = true ]; then
|
|
log "清理未使用的网络..."
|
|
confirm_action "docker network prune -f" && \
|
|
docker network prune -f
|
|
fi
|
|
|
|
# 清理悬空卷(危险操作,默认关闭)
|
|
if [ "$CLEAN_DANGLING_VOLUMES" = true ]; then
|
|
log "警告:即将清理悬空卷,这可能删除重要数据!"
|
|
read -p "确认继续?(y/N): " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
confirm_action "docker volume prune -f" && \
|
|
docker volume prune -f
|
|
else
|
|
log "已跳过卷清理"
|
|
fi
|
|
fi
|
|
|
|
# 使用 system prune 进行最终清理(相对安全)
|
|
log "执行系统清理..."
|
|
confirm_action "docker system prune -f" && \
|
|
docker system prune -f
|
|
|
|
log "清理完成后的 Docker 磁盘使用情况:"
|
|
docker system df
|
|
log "Docker 磁盘清理完成!"
|
|
}
|
|
|
|
# 显示帮助信息
|
|
show_help() {
|
|
cat << EOF
|
|
使用方式: $0 [选项]
|
|
|
|
选项:
|
|
-d, --dry-run 干运行模式,只显示将要执行的操作
|
|
-v, --verbose 详细输出模式
|
|
-h, --help 显示此帮助信息
|
|
|
|
示例:
|
|
$0 # 正常执行清理
|
|
$0 --dry-run # 只显示将要执行的操作而不实际执行
|
|
EOF
|
|
}
|
|
|
|
# 解析命令行参数
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-d|--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
-v|--verbose)
|
|
set -x
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
log "错误: 未知选项 $1"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# 检查 Docker 是否可用
|
|
if ! command -v docker &> /dev/null; then
|
|
log "错误: Docker 未安装或未在 PATH 中找到"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查是否具有 Docker 权限
|
|
if ! docker info &> /dev/null; then
|
|
log "错误: 无 Docker 访问权限或 Docker 守护进程未运行"
|
|
exit 1
|
|
fi
|
|
|
|
# 执行主函数
|
|
clean_docker
|
|
|
|
exit 0 |