自动清理Docker容器的脚本

wen 实用脚本 2

本文目录导读:

自动清理Docker容器的脚本

  1. 基础版:清理已停止的容器
  2. 增强版:多种清理选项
  3. 轻量版:定时任务版本
  4. 使用说明
  5. 安全建议

我来提供一个自动清理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

安全建议

  1. 先使用 --dry-run 测试:确保不会误删重要容器
  2. 设置合理的保留时间:建议保留最近7天的容器
  3. 备份重要数据:清理卷之前确认没有重要数据
  4. 定期检查:每周运行一次清理脚本

这个脚本安全可靠,可以满足大多数Docker清理需求。

抱歉,评论功能暂时关闭!