build-docker-optimized.sh.backup 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. #!/bin/bash
  2. # ============================================
  3. # 快速 Docker 构建脚本 - 使用优化版 Dockerfile
  4. # 使用文档:
  5. # 首次使用: bash init-dependencies.sh
  6. # 构建单个: bash build-docker-optimized.sh gateway:1.0.0
  7. # 构建多个: bash build-docker-optimized.sh gateway:3.0.2 order-service:3.0.5 payment-service:3.0.5
  8. # 自定义仓库: bash build-docker-optimized.sh gateway:1.0.0 -r myregistry.com
  9. # ============================================
  10. set -o pipefail # 管道中任何命令失败都会导致脚本退出
  11. # 颜色定义
  12. RED='\033[0;31m'
  13. GREEN='\033[0;32m'
  14. YELLOW='\033[1;33m'
  15. BLUE='\033[0;34m'
  16. CYAN='\033[0;36m'
  17. NC='\033[0m' # No Color
  18. # 全局构建参数(同一次构建中所有镜像共享)
  19. BUILD_NUMBER=$(date +%Y%m%d%H%M%S)
  20. GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null ; echo "unknown")
  21. # 函数:打印颜色信息
  22. log_info() {
  23. echo -e "${BLUE}[INFO]${NC} $1"
  24. }
  25. log_success() {
  26. echo -e "${GREEN}[✓]${NC} $1"
  27. }
  28. log_error() {
  29. echo -e "${RED}[✗]${NC} $1" >&2
  30. }
  31. log_warn() {
  32. echo -e "${YELLOW}[!]${NC} $1"
  33. }
  34. log_title() {
  35. echo -e "${CYAN}$1${NC}"
  36. }
  37. # 函数:显示使用帮助
  38. show_help() {
  39. cat << EOF
  40. 用法: $0 [OPTIONS] SERVICE:TAG [SERVICE:TAG] ...
  41. 服务简称:
  42. gateway - shop-recycle-gateway 网关服务
  43. order - shop-recycle-order-service 订单服务
  44. order-service - shop-recycle-order-service (别名)
  45. payment - shop-recycle-payment-service 支付服务
  46. payment-service - shop-recycle-payment-service (别名)
  47. 全局选项:
  48. -h, --help 显示此帮助信息
  49. -r, --registry ADDR 镜像仓库地址 (默认: harbor.stardance/shoprecycle)
  50. --no-cache 构建时不使用缓存
  51. --push 构建完成后自动推送到镜像仓库
  52. 示例:
  53. # 构建单个服务
  54. bash $0 gateway:1.0.0
  55. # 构建多个服务(依次进行)
  56. bash $0 gateway:3.0.2 order-service:3.0.5 payment-service:3.0.5
  57. # 自定义镜像仓库
  58. bash $0 gateway:1.0.0 -r myregistry.com
  59. # 禁用缓存并推送
  60. bash $0 gateway:1.0.0 --no-cache --push
  61. EOF
  62. }
  63. # 参数处理
  64. REGISTRY="harbor.stardance/shoprecycle"
  65. NO_CACHE=""
  66. PUSH_IMAGE=false
  67. BUILD_TARGETS=()
  68. # 解析参数
  69. while [[ $# -gt 0 ]]; do
  70. case $1 in
  71. -h|--help)
  72. show_help
  73. exit 0
  74. ;;
  75. -r|--registry)
  76. REGISTRY="$2"
  77. shift 2
  78. ;;
  79. --no-cache)
  80. NO_CACHE="--no-cache"
  81. shift
  82. ;;
  83. --push)
  84. PUSH_IMAGE=true
  85. shift
  86. ;;
  87. *)
  88. # 服务:标签 格式的参数
  89. BUILD_TARGETS+=("$1")
  90. shift
  91. ;;
  92. esac
  93. done
  94. # 验证必要参数
  95. if [ ${#BUILD_TARGETS[@]} -eq 0 ]; then
  96. log_error "缺少构建目标"
  97. echo ""
  98. show_help
  99. exit 1
  100. fi
  101. # 函数:解析 service:tag 格式
  102. parse_service_tag() {
  103. local input="$1"
  104. if [[ ! "$input" =~ : ]]; then
  105. log_error "格式错误: $input (应为 service:tag 格式)"
  106. return 1
  107. fi
  108. local service="${input%%:*}"
  109. local tag="${input##*:}"
  110. # 映射服务名称
  111. local dockerfile=""
  112. local image_name=""
  113. case "$service" in
  114. gateway)
  115. dockerfile="shop-recycle-gateway/Dockerfile.optimized"
  116. image_name="$REGISTRY/shop-recycle-gateway:$tag"
  117. ;;
  118. order|order-service)
  119. dockerfile="shop-recycle-order-service/Dockerfile.optimized"
  120. image_name="$REGISTRY/shop-recycle-order-service:$tag"
  121. ;;
  122. payment|payment-service)
  123. dockerfile="shop-recycle-payment-service/Dockerfile.optimized"
  124. image_name="$REGISTRY/shop-recycle-payment-service:$tag"
  125. ;;
  126. *)
  127. log_error "未知服务: $service"
  128. return 1
  129. ;;
  130. esac
  131. # 输出为 json 格式便于后续处理
  132. echo "{\"service\":\"$service\",\"tag\":\"$tag\",\"dockerfile\":\"$dockerfile\",\"image\":\"$image_name\"}"
  133. }
  134. # 函数:构建单个镜像
  135. build_image() {
  136. local service="$1"
  137. local tag="$2"
  138. local dockerfile="$3"
  139. local image_name="$4"
  140. # 检查 Dockerfile 是否存在
  141. if [ ! -f "$dockerfile" ]; then
  142. log_error "Dockerfile 不存在: $dockerfile"
  143. return 1
  144. fi
  145. local start_time=$(date +%s)
  146. # 打印构建信息
  147. echo ""
  148. log_title "════════════════════════════════════════════════════════════"
  149. log_title "Docker 镜像构建"
  150. log_title "════════════════════════════════════════════════════════════"
  151. log_info "服务: $service"
  152. log_info "镜像标签: $tag"
  153. log_info "仓库地址: $REGISTRY"
  154. log_info "镜像名称: $image_name"
  155. log_info "Git 提交: $GIT_COMMIT"
  156. log_info "构建号: $BUILD_NUMBER"
  157. [ -n "$NO_CACHE" ] && log_warn "禁用构建缓存"
  158. echo ""
  159. log_info "开始构建镜像..."
  160. echo ""
  161. # 执行 Docker 构建(传递全局构建参数)
  162. if docker build $NO_CACHE \
  163. --build-arg BUILD_NUMBER="$BUILD_NUMBER" \
  164. --build-arg GIT_COMMIT="$GIT_COMMIT" \
  165. -t "$image_name" \
  166. -f "$dockerfile" \
  167. .; then
  168. local end_time=$(date +%s)
  169. local duration=$((end_time - start_time))
  170. local minutes=$((duration / 60))
  171. local seconds=$((duration % 60))
  172. echo ""
  173. log_success "════════════════════════════════════════════════════════════"
  174. log_success "构建完成!"
  175. log_success "════════════════════════════════════════════════════════════"
  176. log_success "用时: ${minutes}分${seconds}秒"
  177. echo ""
  178. # 显示镜像信息
  179. log_info "镜像详细信息:"
  180. docker images "$image_name" --no-trunc
  181. echo ""
  182. # 获取镜像大小
  183. local image_size=$(docker images --format "{{.Size}}" "$image_name")
  184. log_info "镜像大小: $image_size"
  185. # 推送镜像
  186. if [ "$PUSH_IMAGE" = true ]; then
  187. echo ""
  188. log_info "准备推送镜像到仓库: $REGISTRY"
  189. if docker push "$image_name"; then
  190. log_success "镜像推送成功!"
  191. else
  192. log_error "镜像推送失败"
  193. return 1
  194. fi
  195. fi
  196. return 0
  197. else
  198. local end_time=$(date +%s)
  199. local duration=$((end_time - start_time))
  200. local minutes=$((duration / 60))
  201. local seconds=$((duration % 60))
  202. echo ""
  203. log_error "════════════════════════════════════════════════════════════"
  204. log_error "构建失败!用时: ${minutes}分${seconds}秒"
  205. log_error "════════════════════════════════════════════════════════════"
  206. echo ""
  207. log_error "调试建议:"
  208. echo " # 查看 Docker 构建日志(详细信息)"
  209. echo " docker build $NO_CACHE --build-arg BUILD_NUMBER=\"$BUILD_NUMBER\" --build-arg GIT_COMMIT=\"$GIT_COMMIT\" -t \"$image_name\" -f \"$dockerfile\" . --progress=plain"
  210. echo ""
  211. return 1
  212. fi
  213. }
  214. # 主程序流程
  215. echo ""
  216. log_title "╔════════════════════════════════════════════════════════════╗"
  217. log_title "║ Shop Recycle Docker 批量构建工具 ║"
  218. log_title "╚════════════════════════════════════════════════════════════╝"
  219. echo ""
  220. # 解析所有构建目标
  221. declare -a services
  222. declare -a tags
  223. declare -a dockerfiles
  224. declare -a images
  225. log_info "解析构建目标..."
  226. for target in "${BUILD_TARGETS[@]}"; do
  227. parsed=$(parse_service_tag "$target")
  228. if [ $? -ne 0 ]; then
  229. log_error "无法解析构建目标: $target"
  230. exit 1
  231. fi
  232. # 从 json 中提取字段
  233. service=$(echo "$parsed" | grep -o '"service":"[^"]*"' | cut -d'"' -f4)
  234. tag=$(echo "$parsed" | grep -o '"tag":"[^"]*"' | cut -d'"' -f4)
  235. dockerfile=$(echo "$parsed" | grep -o '"dockerfile":"[^"]*"' | cut -d'"' -f4)
  236. image=$(echo "$parsed" | grep -o '"image":"[^"]*"' | cut -d'"' -f4)
  237. services+=("$service")
  238. tags+=("$tag")
  239. dockerfiles+=("$dockerfile")
  240. images+=("$image")
  241. log_success "$target"
  242. done
  243. echo ""
  244. log_info "将按顺序构建 ${#BUILD_TARGETS[@]} 个镜像"
  245. log_info "全局构建号: $BUILD_NUMBER"
  246. log_info "全局 Git 提交: $GIT_COMMIT"
  247. # 检查 git 仓库状态
  248. if [ -z "$(git status --porcelain 2>/dev/null)" ]; then
  249. log_success "Git 工作目录干净"
  250. else
  251. log_warn "Git 工作目录有未提交的更改"
  252. fi
  253. echo ""
  254. # 依次构建每个镜像
  255. failed_builds=()
  256. successful_builds=()
  257. for i in "${!services[@]}"; do
  258. echo ""
  259. log_title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  260. log_title "进度: $((i+1))/${#BUILD_TARGETS[@]} - ${BUILD_TARGETS[$i]}"
  261. log_title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  262. if build_image "${services[$i]}" "${tags[$i]}" "${dockerfiles[$i]}" "${images[$i]}"; then
  263. successful_builds+=("${BUILD_TARGETS[$i]}")
  264. else
  265. failed_builds+=("${BUILD_TARGETS[$i]}")
  266. log_error "构建失败: ${BUILD_TARGETS[$i]}"
  267. exit 1
  268. fi
  269. done
  270. # 汇总报告
  271. echo ""
  272. echo ""
  273. log_title "╔════════════════════════════════════════════════════════════╗"
  274. log_title "║ 构建汇总 ║"
  275. log_title "╚════════════════════════════════════════════════════════════╝"
  276. echo ""
  277. log_success "成功构建 ${#successful_builds[@]} 个镜像:"
  278. for build in "${successful_builds[@]}"; do
  279. echo " ✓ $build"
  280. done
  281. if [ ${#failed_builds[@]} -gt 0 ]; then
  282. echo ""
  283. log_error "失败 ${#failed_builds[@]} 个:"
  284. for build in "${failed_builds[@]}"; do
  285. echo " ✗ $build"
  286. done
  287. fi
  288. echo ""
  289. log_info "════════════════════════════════════════════════════════════"
  290. log_info "构建信息:"
  291. log_info "════════════════════════════════════════════════════════════"
  292. log_info "构建号: $BUILD_NUMBER"
  293. log_info "Git 提交: $GIT_COMMIT"
  294. echo ""
  295. log_info "下一步操作:"
  296. log_info "════════════════════════════════════════════════════════════"
  297. echo " # 查看镜像列表"
  298. echo " docker images | grep harbor.stardance/shoprecycle"
  299. echo ""
  300. echo " # 运行容器"
  301. echo " docker run -d -p 8080:8080 --name gateway-container \\"
  302. echo " harbor.stardance/shoprecycle/shop-recycle-gateway:3.0.2"
  303. echo ""
  304. if [ "$PUSH_IMAGE" = false ]; then
  305. echo " # 推送所有镜像到仓库"
  306. for image in "${images[@]}"; do
  307. echo " docker push $image"
  308. done
  309. echo ""
  310. fi
  311. echo ""