Forráskód Böngészése

feat: support multi-service batch build with service:tag format and harbor.stardance as default registry

Builder 2 hónapja
szülő
commit
975c6609ad
1 módosított fájl, 342 hozzáadás és 57 törlés
  1. 342 57
      build-docker-optimized.sh

+ 342 - 57
build-docker-optimized.sh

@@ -2,72 +2,357 @@
 
 # ============================================
 # 快速 Docker 构建脚本 - 使用优化版 Dockerfile
-# 构建前请先执行:bash init-dependencies.sh
+# 使用文档:
+#   首次使用: bash init-dependencies.sh
+#   构建单个: bash build-docker-optimized.sh gateway:1.0.0
+#   构建多个: bash build-docker-optimized.sh gateway:3.0.2 order-service:3.0.5 payment-service:3.0.5
+#   自定义仓库: bash build-docker-optimized.sh gateway:1.0.0 -r myregistry.com
 # ============================================
 
-set -e
-
-SERVICE=${1:-gateway}
-TAG=${2:-latest}
-REGISTRY=${3:-localhost:5000}
-
-BUILD_NUMBER=$(date +%Y%m%d%H%M%S)
-GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
-
-case $SERVICE in
-    gateway)
-        DOCKERFILE="shop-recycle-gateway/Dockerfile.optimized"
-        IMAGE_NAME="$REGISTRY/shop-recycle-gateway:$TAG"
-        ;;
-    order)
-        DOCKERFILE="shop-recycle-order-service/Dockerfile.optimized"
-        IMAGE_NAME="$REGISTRY/shop-recycle-order-service:$TAG"
-        ;;
-    payment)
-        DOCKERFILE="shop-recycle-payment-service/Dockerfile.optimized"
-        IMAGE_NAME="$REGISTRY/shop-recycle-payment-service:$TAG"
-        ;;
-    *)
-        echo "未知服务: $SERVICE"
-        echo "用法: $0 [gateway|order|payment] [tag] [registry]"
-        exit 1
-        ;;
-esac
-
-echo "════════════════════════════════════════════════════════════"
-echo "快速构建 - 使用优化版 Dockerfile"
-echo "════════════════════════════════════════════════════════════"
-echo "服务: $SERVICE"
-echo "TAG: $TAG"
-echo "镜像: $IMAGE_NAME"
-echo "Commit: $GIT_COMMIT"
-echo ""
+set -o pipefail  # 管道中任何命令失败都会导致脚本退出
+
+# 颜色定义
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+CYAN='\033[0;36m'
+NC='\033[0m'  # No Color
+
+# 函数:打印颜色信息
+log_info() {
+    echo -e "${BLUE}[INFO]${NC} $1"
+}
+
+log_success() {
+    echo -e "${GREEN}[✓]${NC} $1"
+}
+
+log_error() {
+    echo -e "${RED}[✗]${NC} $1" >&2
+}
+
+log_warn() {
+    echo -e "${YELLOW}[!]${NC} $1"
+}
+
+log_title() {
+    echo -e "${CYAN}$1${NC}"
+}
+
+# 函数:显示使用帮助
+show_help() {
+    cat << EOF
+用法: $0 [OPTIONS] SERVICE:TAG [SERVICE:TAG] ...
+
+服务简称:
+  gateway         - shop-recycle-gateway 网关服务
+  order           - shop-recycle-order-service 订单服务
+  order-service   - shop-recycle-order-service (别名)
+  payment         - shop-recycle-payment-service 支付服务
+  payment-service - shop-recycle-payment-service (别名)
+
+全局选项:
+  -h, --help              显示此帮助信息
+  -r, --registry ADDR     镜像仓库地址 (默认: harbor.stardance)
+  --no-cache              构建时不使用缓存
+  --push                  构建完成后自动推送到镜像仓库
+
+示例:
+  # 构建单个服务
+  bash $0 gateway:1.0.0
+  
+  # 构建多个服务(依次进行)
+  bash $0 gateway:3.0.2 order-service:3.0.5 payment-service:3.0.5
+  
+  # 自定义镜像仓库
+  bash $0 gateway:1.0.0 -r myregistry.com
+  
+  # 禁用缓存并推送
+  bash $0 gateway:1.0.0 --no-cache --push
 
-# 检查 Dockerfile 是否存在
-if [ ! -f "$DOCKERFILE" ]; then
-    echo "❌ 错误: $DOCKERFILE 不存在"
+EOF
+}
+
+# 参数处理
+REGISTRY="harbor.stardance"
+NO_CACHE=""
+PUSH_IMAGE=false
+BUILD_TARGETS=()
+
+# 解析参数
+while [[ $# -gt 0 ]]; do
+    case $1 in
+        -h|--help)
+            show_help
+            exit 0
+            ;;
+        -r|--registry)
+            REGISTRY="$2"
+            shift 2
+            ;;
+        --no-cache)
+            NO_CACHE="--no-cache"
+            shift
+            ;;
+        --push)
+            PUSH_IMAGE=true
+            shift
+            ;;
+        *)
+            # 服务:标签 格式的参数
+            BUILD_TARGETS+=("$1")
+            shift
+            ;;
+    esac
+done
+
+# 验证必要参数
+if [ ${#BUILD_TARGETS[@]} -eq 0 ]; then
+    log_error "缺少构建目标"
     echo ""
-    echo "首次使用时,请先执行初始化脚本:"
-    echo "  bash init-dependencies.sh"
-    echo "  bash build-docker-optimized.sh $SERVICE $TAG"
+    show_help
     exit 1
 fi
 
-echo ">>> 开始构建..."
-docker build \
-    --build-arg BUILD_NUMBER="$BUILD_NUMBER" \
-    --build-arg GIT_COMMIT="$GIT_COMMIT" \
-    -t "$IMAGE_NAME" \
-    -f "$DOCKERFILE" \
-    .
+# 函数:解析 service:tag 格式
+parse_service_tag() {
+    local input="$1"
+    
+    if [[ ! "$input" =~ : ]]; then
+        log_error "格式错误: $input (应为 service:tag 格式)"
+        return 1
+    fi
+    
+    local service="${input%%:*}"
+    local tag="${input##*:}"
+    
+    # 映射服务名称
+    local dockerfile=""
+    local image_name=""
+    
+    case "$service" in
+        gateway)
+            dockerfile="shop-recycle-gateway/Dockerfile.optimized"
+            image_name="$REGISTRY/shop-recycle-gateway:$tag"
+            ;;
+        order|order-service)
+            dockerfile="shop-recycle-order-service/Dockerfile.optimized"
+            image_name="$REGISTRY/shop-recycle-order-service:$tag"
+            ;;
+        payment|payment-service)
+            dockerfile="shop-recycle-payment-service/Dockerfile.optimized"
+            image_name="$REGISTRY/shop-recycle-payment-service:$tag"
+            ;;
+        *)
+            log_error "未知服务: $service"
+            return 1
+            ;;
+    esac
+    
+    # 输出为 json 格式便于后续处理
+    echo "{\"service\":\"$service\",\"tag\":\"$tag\",\"dockerfile\":\"$dockerfile\",\"image\":\"$image_name\"}"
+}
+
+# 函数:构建单个镜像
+build_image() {
+    local service="$1"
+    local tag="$2"
+    local dockerfile="$3"
+    local image_name="$4"
+    
+    # 检查 Dockerfile 是否存在
+    if [ ! -f "$dockerfile" ]; then
+        log_error "Dockerfile 不存在: $dockerfile"
+        return 1
+    fi
+    
+    local build_number=$(date +%Y%m%d%H%M%S)
+    local git_commit=$(git rev-parse --short HEAD 2>/dev/null ; echo "unknown")
+    local start_time=$(date +%s)
+    
+    # 打印构建信息
+    echo ""
+    log_title "════════════════════════════════════════════════════════════"
+    log_title "Docker 镜像构建"
+    log_title "════════════════════════════════════════════════════════════"
+    log_info "服务:      $service"
+    log_info "镜像标签:  $tag"
+    log_info "仓库地址:  $REGISTRY"
+    log_info "镜像名称:  $image_name"
+    log_info "Git 提交:  $git_commit"
+    log_info "构建号:    $build_number"
+    [ -n "$NO_CACHE" ] && log_warn "禁用构建缓存"
+    echo ""
+    
+    log_info "开始构建镜像..."
+    echo ""
+    
+    # 执行 Docker 构建
+    if docker build $NO_CACHE \
+        --build-arg BUILD_NUMBER="$build_number" \
+        --build-arg GIT_COMMIT="$git_commit" \
+        -t "$image_name" \
+        -f "$dockerfile" \
+        .; then
+        
+        local end_time=$(date +%s)
+        local duration=$((end_time - start_time))
+        local minutes=$((duration / 60))
+        local seconds=$((duration % 60))
+        
+        echo ""
+        log_success "════════════════════════════════════════════════════════════"
+        log_success "构建完成!"
+        log_success "════════════════════════════════════════════════════════════"
+        log_success "用时: ${minutes}分${seconds}秒"
+        echo ""
+        
+        # 显示镜像信息
+        log_info "镜像详细信息:"
+        docker images "$image_name" --no-trunc
+        echo ""
+        
+        # 获取镜像大小
+        local image_size=$(docker images --format "{{.Size}}" "$image_name")
+        log_info "镜像大小: $image_size"
+        
+        # 推送镜像
+        if [ "$PUSH_IMAGE" = true ]; then
+            echo ""
+            log_info "准备推送镜像到仓库: $REGISTRY"
+            if docker push "$image_name"; then
+                log_success "镜像推送成功!"
+            else
+                log_error "镜像推送失败"
+                return 1
+            fi
+        fi
+        
+        return 0
+    else
+        local end_time=$(date +%s)
+        local duration=$((end_time - start_time))
+        local minutes=$((duration / 60))
+        local seconds=$((duration % 60))
+        
+        echo ""
+        log_error "════════════════════════════════════════════════════════════"
+        log_error "构建失败!用时: ${minutes}分${seconds}秒"
+        log_error "════════════════════════════════════════════════════════════"
+        echo ""
+        log_error "调试建议:"
+        echo "  # 查看 Docker 构建日志(详细信息)"
+        echo "  docker build $NO_CACHE --build-arg BUILD_NUMBER=\"$build_number\" -t \"$image_name\" -f \"$dockerfile\" . --progress=plain"
+        echo ""
+        return 1
+    fi
+}
+
+# 主程序流程
+echo ""
+log_title "╔════════════════════════════════════════════════════════════╗"
+log_title "║         Shop Recycle Docker 批量构建工具                   ║"
+log_title "╚════════════════════════════════════════════════════════════╝"
+echo ""
+
+# 解析所有构建目标
+declare -a services
+declare -a tags
+declare -a dockerfiles
+declare -a images
+
+log_info "解析构建目标..."
+for target in "${BUILD_TARGETS[@]}"; do
+    parsed=$(parse_service_tag "$target")
+    if [ $? -ne 0 ]; then
+        log_error "无法解析构建目标: $target"
+        exit 1
+    fi
+    
+    # 从 json 中提取字段
+    service=$(echo "$parsed" | grep -o '"service":"[^"]*"' | cut -d'"' -f4)
+    tag=$(echo "$parsed" | grep -o '"tag":"[^"]*"' | cut -d'"' -f4)
+    dockerfile=$(echo "$parsed" | grep -o '"dockerfile":"[^"]*"' | cut -d'"' -f4)
+    image=$(echo "$parsed" | grep -o '"image":"[^"]*"' | cut -d'"' -f4)
+    
+    services+=("$service")
+    tags+=("$tag")
+    dockerfiles+=("$dockerfile")
+    images+=("$image")
+    
+    log_success "$target"
+done
+
+echo ""
+log_info "将按顺序构建 ${#BUILD_TARGETS[@]} 个镜像"
+
+# 检查 git 仓库状态
+if [ -z "$(git status --porcelain 2>/dev/null)" ]; then
+    log_success "Git 工作目录干净"
+else
+    log_warn "Git 工作目录有未提交的更改"
+fi
+
+echo ""
+
+# 依次构建每个镜像
+failed_builds=()
+successful_builds=()
+
+for i in "${!services[@]}"; do
+    echo ""
+    log_title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+    log_title "进度: $((i+1))/${#BUILD_TARGETS[@]} - ${BUILD_TARGETS[$i]}"
+    log_title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+    
+    if build_image "${services[$i]}" "${tags[$i]}" "${dockerfiles[$i]}" "${images[$i]}"; then
+        successful_builds+=("${BUILD_TARGETS[$i]}")
+    else
+        failed_builds+=("${BUILD_TARGETS[$i]}")
+        log_error "构建失败: ${BUILD_TARGETS[$i]}"
+        exit 1
+    fi
+done
 
+# 汇总报告
 echo ""
-echo "════════════════════════════════════════════════════════════"
-echo "✅ 构建完成!"
-echo "════════════════════════════════════════════════════════════"
 echo ""
-echo "镜像详细信息:"
-docker images | grep "$REGISTRY" | head -3
+log_title "╔════════════════════════════════════════════════════════════╗"
+log_title "║                     构建汇总                               ║"
+log_title "╚════════════════════════════════════════════════════════════╝"
+echo ""
+
+log_success "成功构建 ${#successful_builds[@]} 个镜像:"
+for build in "${successful_builds[@]}"; do
+    echo "  ✓ $build"
+done
+
+if [ ${#failed_builds[@]} -gt 0 ]; then
+    echo ""
+    log_error "失败 ${#failed_builds[@]} 个:"
+    for build in "${failed_builds[@]}"; do
+        echo "  ✗ $build"
+    done
+fi
 
 echo ""
-echo "运行容器: docker run -d -p 8080:8080 $IMAGE_NAME"
+log_info "════════════════════════════════════════════════════════════"
+log_info "下一步操作:"
+log_info "════════════════════════════════════════════════════════════"
+echo "  # 查看镜像列表"
+echo "  docker images | grep harbor.stardance"
+echo ""
+echo "  # 运行容器"
+echo "  docker run -d -p 8080:8080 --name gateway-container \\"
+echo "    harbor.stardance/shop-recycle-gateway:3.0.2"
+echo ""
+if [ "$PUSH_IMAGE" = false ]; then
+    echo "  # 推送所有镜像到仓库"
+    for image in "${images[@]}"; do
+        echo "  docker push $image"
+    done
+    echo ""
+fi
+echo ""
+