本文目录导读:

我来提供一个自动清理Docker容器的Shell脚本,包含多种清理选项:
基础版:清理已停止的容器
#!/bin/bash
# 自动清理已停止的Docker容器
echo "====== Docker 容器清理脚本 ======"
echo "开始时间: $(date)"
# 查找并列出所有已停止的容器
stopped_containers=$(docker ps -a -q -f status=exited -f status=created)
if [ -z "$stopped_containers" ]; then
echo "没有需要清理的已停止容器。"
else
echo "发现已停止容器数量: $(echo "$stopped_containers" | wc -l)"
echo "正在删除容器..."
docker rm $stopped_containers
echo "容器清理完成!"
fi
echo "结束时间: $(date)"
echo "================================"
增强版:多种清理选项
#!/bin/bash
# Docker 容器/镜像/卷 自动清理脚本
# 使用方法: ./docker_cleanup.sh [选项]
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 默认设置
DRY_RUN=false
CLEAN_ALL=false
DAYS_OLD=7
print_banner() {
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Docker 自动清理工具 ${NC}"
echo -e "${GREEN}========================================${NC}"
}
show_help() {
echo "使用方法: $0 [选项]"
echo ""
echo "选项:"
echo " -h, --help 显示帮助信息"
echo " -d, --dry-run 仅显示将要删除的内容,不实际删除"
echo " -a, --all 清理所有资源(容器、镜像、卷、构建缓存)"
echo " -c, --containers 仅清理容器"
echo " -i, --images 清理无标签镜像"
echo " -v, --volumes 清理未使用的卷"
echo " --days N 清理N天前的容器(默认7天)"
echo ""
echo "示例:"
echo " $0 --dry-run 预览将要清理的内容"
echo " $0 --all 完全清理"
echo " $0 --days 1 清理一天前的容器"
}
# 清理容器
cleanup_containers() {
echo -e "\n${YELLOW}[1/4] 清理容器...${NC}"
# 清理已停止的容器
if [ "$DRY_RUN" = true ]; then
echo "(预览模式)将删除以下容器:"
docker ps -a -q -f status=exited -f status=created 2>/dev/null || echo "无"
else
local cleaned=$(docker ps -a -q -f status=exited -f status=created | wc -l)
if [ "$cleaned" -gt 0 ]; then
docker ps -a -q -f status=exited -f status=created | xargs -r docker rm
echo -e "${GREEN}已删除 $cleaned 个停止的容器${NC}"
else
echo -e "${GREEN}没有需要清理的已停止容器${NC}"
fi
fi
# 清理旧的容器(超过指定天数)
if [ "$DAYS_OLD" -gt 0 ]; then
local old_containers=$(docker ps -a -q -f "before=$(date -d "$DAYS_OLD days ago" +%Y-%m-%d)" 2>/dev/null)
if [ -n "$old_containers" ]; then
local count=$(echo "$old_containers" | wc -l)
if [ "$DRY_RUN" = true ]; then
echo "(预览模式)将删除 $count 个超过 $DAYS_OLD 天的容器"
else
echo "$old_containers" | xargs -r docker rm -f
echo -e "${GREEN}已删除 $count 个超过 $DAYS_OLD 天的容器${NC}"
fi
fi
fi
}
# 清理镜像
cleanup_images() {
echo -e "\n${YELLOW}[2/4] 清理无标签镜像...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "(预览模式)将删除以下无标签镜像:"
docker images -f "dangling=true" --format "table {{.ID}}\t{{.Repository}}:{{.Tag}}" 2>/dev/null || echo "无"
else
local cleaned=$(docker images -f "dangling=true" -q | wc -l)
if [ "$cleaned" -gt 0 ]; then
docker image prune -f
echo -e "${GREEN}已清理 $cleaned 个无标签镜像${NC}"
else
echo -e "${GREEN}没有需要清理的无标签镜像${NC}"
fi
fi
# 如果启用完全清理,删除所有未使用的镜像
if [ "$CLEAN_ALL" = true ]; then
echo -e "\n${YELLOW}清理所有未使用的镜像...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "(预览模式)将检查所有未使用的镜像"
else
docker image prune -a -f
fi
fi
}
# 清理卷
cleanup_volumes() {
echo -e "\n${YELLOW}[3/4] 清理未使用的卷...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "(预览模式)将删除以下未使用的卷:"
docker volume ls -qf dangling=true 2>/dev/null || echo "无"
else
local cleaned=$(docker volume ls -qf dangling=true | wc -l)
if [ "$cleaned" -gt 0 ]; then
docker volume prune -f
echo -e "${GREEN}已清理 $cleaned 个未使用的卷${NC}"
else
echo -e "${GREEN}没有需要清理的未使用卷${NC}"
fi
fi
}
# 清理构建缓存
cleanup_build_cache() {
echo -e "\n${YELLOW}[4/4] 清理Docker构建缓存...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "(预览模式)将计算缓存大小"
docker system df 2>/dev/null || true
else
if command -v docker &> /dev/null; then
# 检查是否使用BuildKit
if docker info 2>/dev/null | grep -q "BuildKit"; then
docker builder prune -a -f
else
docker system prune -f
fi
echo -e "${GREEN}构建缓存已清理${NC}"
fi
fi
}
# 显示磁盘使用情况
show_disk_usage() {
echo -e "\n${GREEN}清理后的磁盘使用情况:${NC}"
docker system df 2>/dev/null || true
}
# 主函数
main() {
print_banner
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-d|--dry-run)
DRY_RUN=true
shift
;;
-a|--all)
CLEAN_ALL=true
shift
;;
-c|--containers)
cleanup_containers
show_disk_usage
exit 0
;;
-i|--images)
cleanup_images
show_disk_usage
exit 0
;;
-v|--volumes)
cleanup_volumes
show_disk_usage
exit 0
;;
--days)
DAYS_OLD="$2"
shift 2
;;
*)
echo -e "${RED}未知参数: $1${NC}"
show_help
exit 1
;;
esac
done
# 执行清理
if [ "$DRY_RUN" = true ]; then
echo -e "${YELLOW}运行在预览模式,不会实际删除任何内容${NC}"
fi
cleanup_containers
cleanup_images
cleanup_volumes
cleanup_build_cache
# 显示磁盘使用情况
show_disk_usage
echo -e "\n${GREEN}清理完成!${NC}"
}
# 执行主函数
main "$@"
轻量版:定时任务版本
#!/bin/bash # 简单的定时清理脚本(适合cron使用) # 保存为 /usr/local/bin/docker_cleanup_cron.sh LOG_FILE="/var/log/docker_cleanup.log" echo "=== Docker清理 $(date) ===" >> $LOG_FILE # 清理停止的容器 docker container prune -f >> $LOG_FILE 2>&1 # 清理无标签镜像 docker image prune -f >> $LOG_FILE 2>&1 # 清理未使用的卷 docker volume prune -f >> $LOG_FILE 2>&1 # 清理网络 docker network prune -f >> $LOG_FILE 2>&1 echo "清理完成" >> $LOG_FILE
使用说明
保存脚本
# 保存为文件 vim docker_cleanup.sh chmod +x docker_cleanup.sh
使用方法
# 查看帮助 ./docker_cleanup.sh --help # 预览模式(不会实际删除) ./docker_cleanup.sh --dry-run # 全面清理 ./docker_cleanup.sh --all # 仅清理容器 ./docker_cleanup.sh --containers # 清理1天前的容器 ./docker_cleanup.sh --days 1
设置定时任务(crontab)
# 编辑crontab crontab -e # 每天凌晨2点执行清理 0 2 * * * /path/to/docker_cleanup.sh --all --days 7 >> /var/log/docker_cleanup_cron.log 2>&1
安全建议
- 先使用
--dry-run测试:确保不会误删重要容器 - 设置合理的保留时间:建议保留最近7天的容器
- 备份重要数据:清理卷之前确认没有重要数据
- 定期检查:每周运行一次清理脚本
这个脚本安全可靠,可以满足大多数Docker清理需求。