- 更新 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]>
432 lines
12 KiB
Bash
Executable File
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 "$@" |