Files
macos-tools/scripts/smart-docker-build.sh
gaoandClaude 8f47f4e9ea feat: 完善 DevOps 工具链配置和优化 Harbor 服务
- 更新 Gitea runner 配置,支持优化的 CI/CD 环境
- 完善 Harbor HTTPS 配置和远程访问支持
- 优化 Harbor 日志配置,改用 json-file 驱动
- 添加 Docker 构建加速和代理缓存脚本
- 新增完整的文档和使用指南
- 添加 AI 开发工具集成配置

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
2025-11-03 06:39:53 +08:00

432 lines
12 KiB
Bash
Executable File

#!/bin/bash
# 智能 Docker 构建脚本
# 自动检测网络环境,选择最优构建策略
# 集成代理、缓存、多架构等优化方案
set -e
# 配置变量
HARBOR_REGISTRY="192.168.1.83:8443"
HARBOR_USER="admin"
HARBOR_PASS="admin123"
APT_CACHER_PORT="${APT_CACHER_PORT:-3142}"
# 自动检测代理
AUTO_DETECT_PROXY=true
USE_BUILDKIT=true
ENABLE_CACHE=true
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'
info() { echo -e "${BLUE}INFO: $1${NC}"; }
success() { echo -e "${GREEN}SUCCESS: $1${NC}"; }
warning() { echo -e "${YELLOW}WARNING: $1${NC}"; }
error() { echo -e "${RED}ERROR: $1${NC}"; }
header() { echo -e "${PURPLE}🚀 $1${NC}"; }
step() { echo -e "${CYAN}▶ $1${NC}"; }
# 显示帮助信息
show_help() {
cat << EOF
智能 Docker 构建脚本
用法: $0 [选项] <镜像名> [标签] [Dockerfile路径]
参数:
镜像名 目标镜像名称 (必需)
标签 镜像标签 (默认: latest)
Dockerfile路径 Dockerfile 路径 (默认: ./Dockerfile)
选项:
-h, --help 显示此帮助信息
-p, --proxy URL 强制使用指定代理
--no-proxy 禁用代理
--no-cache 禁用构建缓存
--no-buildkit 禁用 BuildKit
--multi-arch 启用多架构构建
--push 构建后推送到 Harbor
--platform ARCH 指定平台 (linux/amd64, linux/arm64)
--strategy STRATEGY 构建策略 (auto, proxy, cache, direct)
--verbose 详细输出
--dry-run 仅显示构建命令,不执行
构建策略:
auto - 自动检测最优策略 (默认)
proxy - 强制使用代理
cache - 强制使用缓存服务
direct - 直接构建,不使用优化
示例:
$0 myapp # 自动优化构建
$0 myapp v1.0.0 # 指定标签
$0 --multi-arch --push myapp # 多架构构建并推送
$0 --strategy proxy myapp # 强制使用代理
$0 --platform linux/arm64 myapp # 指定架构
EOF
}
# 解析命令行参数
parse_args() {
IMAGE_NAME=""
IMAGE_TAG="latest"
DOCKERFILE_PATH="./Dockerfile"
PROXY_URL=""
STRATEGY="auto"
MULTI_ARCH=false
PUSH_TO_HARBOR=false
PLATFORM=""
VERBOSE=false
DRY_RUN=false
USE_PROXY=true
USE_BUILDKIT_CACHE=true
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-p|--proxy)
PROXY_URL="$2"
shift 2
;;
--no-proxy)
USE_PROXY=false
shift
;;
--no-cache)
ENABLE_CACHE=false
shift
;;
--no-buildkit)
USE_BUILDKIT=false
shift
;;
--multi-arch)
MULTI_ARCH=true
shift
;;
--push)
PUSH_TO_HARBOR=true
shift
;;
--platform)
PLATFORM="$2"
shift 2
;;
--strategy)
STRATEGY="$2"
shift 2
;;
--verbose)
VERBOSE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
-*)
error "未知选项: $1"
show_help
exit 1
;;
*)
if [ -z "$IMAGE_NAME" ]; then
IMAGE_NAME="$1"
elif [ -z "$IMAGE_TAG" ]; then
IMAGE_TAG="$1"
else
DOCKERFILE_PATH="$1"
fi
shift
;;
esac
done
# 验证必需参数
if [ -z "$IMAGE_NAME" ]; then
error "必须指定镜像名称"
show_help
exit 1
fi
# 检查 Dockerfile 是否存在
if [ ! -f "$DOCKERFILE_PATH" ]; then
error "Dockerfile 不存在: $DOCKERFILE_PATH"
exit 1
fi
}
# 检测系统环境
detect_environment() {
header "检测构建环境..."
# Docker 环境
if command -v docker > /dev/null; then
info "Docker 版本: $(docker --version)"
if docker buildx version > /dev/null 2>&1; then
info "BuildKit: 可用"
BUILDKIT_AVAILABLE=true
else
warning "BuildKit: 不可用"
BUILDKIT_AVAILABLE=false
fi
else
error "Docker 未安装"
exit 1
fi
# 网络环境检测
info "检测网络环境..."
# 测试直接连接
if timeout 10 curl -s http://deb.debian.org > /dev/null 2>&1; then
info "✅ 外网直连正常"
DIRECT_CONNECT=true
else
info "❌ 外网直连异常"
DIRECT_CONNECT=false
fi
# 代理检测
if [ "$AUTO_DETECT_PROXY" = true ] && [ -z "$PROXY_URL" ]; then
for port in 7890 1087 8080 8888; do
if timeout 3 nc -z localhost $port 2>/dev/null; then
PROXY_URL="http://127.0.0.1:$port"
info "✅ 检测到代理: $PROXY_URL"
break
fi
done
fi
# APT 缓存检测
if timeout 3 curl -s "http://localhost:$APT_CACHER_PORT" > /dev/null 2>&1; then
info "✅ APT 缓存服务可用: http://localhost:$APT_CACHER_PORT"
APT_CACHE_AVAILABLE=true
else
info "❌ APT 缓存服务不可用"
APT_CACHE_AVAILABLE=false
fi
# Harbor 连接检测
if timeout 10 curl -sk "https://$HARBOR_REGISTRY/api/v2.0/health" > /dev/null 2>&1; then
info "✅ Harbor 服务可用"
HARBOR_AVAILABLE=true
else
info "❌ Harbor 服务不可用"
HARBOR_AVAILABLE=false
fi
success "环境检测完成"
}
# 选择构建策略
select_build_strategy() {
local selected_strategy="$STRATEGY"
if [ "$STRATEGY" = "auto" ]; then
info "自动选择最优构建策略..."
# 优先级: 代理 > 缓存 > 直接
if [ -n "$PROXY_URL" ] && [ "$USE_PROXY" = true ]; then
selected_strategy="proxy"
elif [ "$APT_CACHE_AVAILABLE" = true ]; then
selected_strategy="cache"
elif [ "$DIRECT_CONNECT" = true ]; then
selected_strategy="direct"
else
selected_strategy="proxy" # 最后尝试代理
warning "网络环境较差,将尝试使用代理"
fi
fi
info "选择构建策略: $selected_strategy"
STRATEGY="$selected_strategy"
}
# 生成构建命令
generate_build_command() {
local build_cmd="docker build"
local build_args=()
# 添加 BuildKit 支持
if [ "$USE_BUILDKIT" = true ] && [ "$BUILDKIT_AVAILABLE" = true ]; then
export DOCKER_BUILDKIT=1
build_args+=("--build-arg" "BUILDKIT_INLINE_CACHE=1")
fi
# 添加平台参数
if [ -n "$PLATFORM" ]; then
build_args+=("--platform" "$PLATFORM")
elif [ "$MULTI_ARCH" = true ]; then
build_args+=("--platform" "linux/amd64,linux/arm64")
fi
# 根据策略添加参数
case "$STRATEGY" in
proxy)
if [ -n "$PROXY_URL" ]; then
build_args+=("--build-arg" "HTTP_PROXY=$PROXY_URL")
build_args+=("--build-arg" "HTTPS_PROXY=$PROXY_URL")
build_args+=("--build-arg" "NO_PROXY=localhost,127.0.0.1,$HARBOR_REGISTRY")
info "使用代理: $PROXY_URL"
else
warning "代理策略但未找到代理地址"
fi
;;
cache)
build_args+=("--build-arg" "APT_PROXY=http://host.docker.internal:$APT_CACHER_PORT")
info "使用 APT 缓存: http://host.docker.internal:$APT_CACHER_PORT"
;;
esac
# 添加缓存支持
if [ "$ENABLE_CACHE" = true ] && [ "$HARBOR_AVAILABLE" = true ]; then
build_args+=("--cache-from" "type=registry,ref=$HARBOR_REGISTRY/build-cache/$IMAGE_NAME:buildcache")
if [ "$USE_BUILDKIT_CACHE" = true ]; then
build_args+=("--cache-to" "type=registry,ref=$HARBOR_REGISTRY/build-cache/$IMAGE_NAME:buildcache,mode=max")
fi
info "启用构建缓存"
fi
# 添加标签
local full_image_name="$IMAGE_NAME:$IMAGE_TAG"
if [ "$PUSH_TO_HARBOR" = true ] && [ "$HARBOR_AVAILABLE" = true ]; then
full_image_name="$HARBOR_REGISTRY/library/$IMAGE_NAME:$IMAGE_TAG"
build_args+=("-t" "$full_image_name")
else
build_args+=("-t" "$full_image_name")
fi
# 多架构构建需要 --push
if [ "$MULTI_ARCH" = true ]; then
build_args+=("--push")
fi
# 添加 Dockerfile 路径
build_args+=("-f" "$DOCKERFILE_PATH")
build_args+=(".")
# 组装完整命令
for arg in "${build_args[@]}"; do
build_cmd="$build_cmd $arg"
done
echo "$build_cmd"
}
# 执行构建
execute_build() {
header "开始构建镜像..."
local build_cmd=$(generate_build_command)
if [ "$VERBOSE" = true ] || [ "$DRY_RUN" = true ]; then
info "构建命令:"
echo "$build_cmd"
echo ""
fi
if [ "$DRY_RUN" = false ]; then
# 登录 Harbor (如果需要推送)
if [ "$PUSH_TO_HARBOR" = true ] && [ "$HARBOR_AVAILABLE" = true ]; then
info "登录 Harbor..."
echo "$HARBOR_PASS" | docker login "$HARBOR_REGISTRY" -u "$HARBOR_USER" --password-stdin
fi
info "执行构建..."
eval "$build_cmd"
if [ "$MULTI_ARCH" = false ]; then
success "构建完成: $full_image_name"
else
success "多架构构建完成"
fi
# 显示镜像信息
if [ "$MULTI_ARCH" = false ] && command -v docker > /dev/null; then
info "镜像信息:"
docker images "$IMAGE_NAME:$IMAGE_TAG" 2>/dev/null || true
fi
fi
}
# 显示构建后信息
show_post_build_info() {
header "构建信息"
echo ""
echo "📦 镜像信息:"
echo " 名称: $IMAGE_NAME:$IMAGE_TAG"
if [ "$PUSH_TO_HARBOR" = true ] && [ "$HARBOR_AVAILABLE" = true ]; then
echo " Harbor: $HARBOR_REGISTRY/library/$IMAGE_NAME:$IMAGE_TAG"
fi
if [ "$MULTI_ARCH" = true ]; then
echo " 架构: linux/amd64, linux/arm64"
fi
echo ""
echo "🔧 构建配置:"
echo " 策略: $STRATEGY"
echo " BuildKit: $([ "$USE_BUILDKIT" = true ] && echo "启用" || echo "禁用")"
echo " 缓存: $([ "$ENABLE_CACHE" = true ] && echo "启用" || echo "禁用")"
if [ -n "$PROXY_URL" ]; then
echo " 代理: $PROXY_URL"
fi
echo ""
echo "🚀 使用方法:"
echo " docker run $IMAGE_NAME:$IMAGE_TAG"
if [ "$PUSH_TO_HARBOR" = true ] && [ "$HARBOR_AVAILABLE" = true ]; then
echo " docker run $HARBOR_REGISTRY/library/$IMAGE_NAME:$IMAGE_TAG"
fi
echo ""
# 性能提示
if [ "$STRATEGY" = "proxy" ]; then
info "💡 提示: 使用代理构建,首次可能较慢,后续会显著加速"
elif [ "$STRATEGY" = "cache" ]; then
info "💡 提示: 使用本地缓存,构建速度将显著提升"
fi
if [ "$MULTI_ARCH" = true ]; then
info "💡 提示: 多架构镜像已推送到 Harbor,可在不同架构的机器上使用"
fi
}
# 主函数
main() {
# 解析参数
parse_args "$@"
header "智能 Docker 构建工具"
echo ""
# 检测环境
detect_environment
echo ""
# 选择策略
select_build_strategy
echo ""
# 执行构建
execute_build
echo ""
# 显示结果
show_post_build_info
}
# 执行主函数
main "$@"