7cbb7a9ac8
ci/woodpecker/push/woodpecker Pipeline failed
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 触发滚动事件 - 修复组件渲染测试
233 lines
5.7 KiB
Bash
Executable File
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
|