Files
novalon-website/scripts/production-docker-cleanup.sh
T
张翔 7cbb7a9ac8
ci/woodpecker/push/woodpecker Pipeline failed
fix(test): 修复测试环境问题
1. jest.setup.js:
   - 添加 Request/Response/Headers 全局对象 mock
   - 解决 'Request is not defined' 错误

2. .eslintrc.json:
   - 将 jest.setup.js 添加到忽略列表

3. shared-mocks.tsx:
   - 添加 ArrowUp 图标 mock

4. back-to-top.test.tsx:
   - 重写测试使用 import 语法
   - 使用 fireEvent.scroll 触发滚动事件
   - 修复组件渲染测试
2026-03-29 14:50:09 +08:00

233 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
# 生产环境Docker镜像瘦身脚本
# 用途:安全清理未使用的Docker镜像
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
separator() {
echo "======================================================================"
}
# 记录日志
LOG_FILE="/tmp/docker-cleanup-$(date +%Y%m%d_%H%M%S).log"
exec > >(tee -a "$LOG_FILE") 2>&1
separator
echo "生产环境Docker镜像瘦身脚本"
echo "执行时间: $(date)"
separator
# 1. 显示当前状态
log_info "步骤1: 当前Docker资源使用情况"
separator
echo ""
docker system df
echo ""
log_info "当前镜像列表:"
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}"
echo ""
log_info "运行中的容器:"
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
# 2. 分析未使用的镜像
separator
log_info "步骤2: 分析未使用的镜像"
separator
echo ""
log_info "悬空镜像(<none>标签):"
DANGLING_IMAGES=$(docker images -f "dangling=true" -q)
if [ -n "$DANGLING_IMAGES" ]; then
docker images -f "dangling=true" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}"
DANGLING_SIZE=$(docker images -f "dangling=true" --format "{{.Size}}" | grep -oE '[0-9.]+[GM]' | head -1)
log_warning "发现悬空镜像,总计约: $DANGLING_SIZE"
else
log_success "没有悬空镜像"
fi
echo ""
log_info "检查哪些镜像正在被使用..."
RUNNING_IMAGES=$(docker ps --format "{{.Image}}" | sort -u)
log_info "正在使用的镜像:"
echo "$RUNNING_IMAGES"
echo ""
log_info "未被容器使用的镜像:"
docker images --format "{{.Repository}}:{{.Tag}}" | while read image; do
if ! echo "$RUNNING_IMAGES" | grep -q "$(echo $image | cut -d: -f1)"; then
echo "$image"
fi
done
# 3. 清理悬空镜像(安全)
separator
log_info "步骤3: 清理悬空镜像"
separator
if [ -n "$DANGLING_IMAGES" ]; then
log_warning "将删除以下悬空镜像:"
docker images -f "dangling=true" --format "{{.ID}}\t{{.Size}}"
echo ""
read -p "确认删除悬空镜像?(y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "正在清理悬空镜像..."
docker image prune -f
log_success "悬空镜像清理完成"
else
log_info "跳过悬空镜像清理"
fi
else
log_success "没有悬空镜像需要清理"
fi
# 4. 清理旧版本镜像(谨慎)
separator
log_info "步骤4: 清理旧版本镜像"
separator
echo ""
log_info "检查novalon-website镜像版本..."
NOVALON_IMAGES=$(docker images "novalon-website" --format "{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}")
echo "$NOVALON_IMAGES"
echo ""
log_info "当前使用的版本:"
docker ps --filter "name=novalon-website" --format "{{.Image}}"
# 检查是否有旧版本
OLD_VERSIONS=$(docker images "novalon-website" --format "{{.Tag}}" | grep -v "latest" | head -n -1)
if [ -n "$OLD_VERSIONS" ]; then
log_warning "发现旧版本镜像:"
echo "$OLD_VERSIONS"
echo ""
read -p "是否删除旧版本镜像?(y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
for version in $OLD_VERSIONS; do
log_info "删除镜像: novalon-website:$version"
docker rmi "novalon-website:$version" || log_warning "无法删除 novalon-website:$version(可能正在使用)"
done
log_success "旧版本镜像清理完成"
else
log_info "跳过旧版本镜像清理"
fi
else
log_success "没有旧版本镜像需要清理"
fi
# 5. 清理构建缓存
separator
log_info "步骤5: 清理构建缓存"
separator
CACHE_SIZE=$(docker system df | grep "Build Cache" | awk '{print $3}')
log_info "构建缓存大小: $CACHE_SIZE"
if [ "$CACHE_SIZE" != "0B" ]; then
read -p "是否清理构建缓存?(y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "正在清理构建缓存..."
docker builder prune -a -f
log_success "构建缓存清理完成"
else
log_info "跳过构建缓存清理"
fi
else
log_success "没有构建缓存需要清理"
fi
# 6. 清理未使用的卷(可选)
separator
log_info "步骤6: 清理未使用的卷(可选)"
separator
UNUSED_VOLUMES=$(docker volume ls -q --filter "dangling=true")
if [ -n "$UNUSED_VOLUMES" ]; then
log_warning "发现未使用的卷:"
echo "$UNUSED_VOLUMES"
read -p "是否清理未使用的卷?(y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "正在清理未使用的卷..."
docker volume prune -f
log_success "未使用卷清理完成"
else
log_info "跳过未使用卷清理"
fi
else
log_success "没有未使用的卷"
fi
# 7. 显示清理结果
separator
log_info "步骤7: 清理结果"
separator
echo ""
log_info "清理后的Docker资源使用情况:"
docker system df
echo ""
log_info "磁盘空间变化:"
df -h | grep -E "Filesystem|/$"
separator
log_success "Docker镜像瘦身完成"
separator
echo ""
log_info "清理摘要:"
echo " ✅ 悬空镜像已清理"
echo " ✅ 旧版本镜像已清理"
echo " ✅ 构建缓存已清理"
echo " ✅ 未使用卷已清理"
echo ""
log_info "详细日志已保存到: $LOG_FILE"
echo ""
log_warning "建议后续操作:"
echo " 1. 监控服务状态: docker ps"
echo " 2. 验证应用访问: curl -I https://novalon.cn"
echo " 3. 设置定期清理: crontab -e"
echo " 4. 配置日志轮转: /etc/logrotate.d/docker"
separator