Files
urbanLifeline/docker/build.sh
2025-12-28 18:30:17 +08:00

382 lines
10 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
##############################################
# Urban Lifeline - 构建和打包脚本
#
# 功能:
# 1. 编译后端/前端项目
# 2. 构建 Docker 镜像
# 3. 导出镜像到 tar 文件
#
# 使用方法:
# ./build.sh [target] [options]
#
# 目标(target)
# base - 构建基础镜像
# serv - 构建所有后端服务镜像
# web - 构建前端镜像
# all - 构建所有镜像(默认)
# gateway - 构建单个后端服务
# system/auth/file/ai/workcase - 同上
#
# 选项(options)
# compile - 先编译代码再构建镜像
# save - 构建后导出镜像到 tar 文件
# save=VERSION - 导出指定版本的镜像
#
# 示例:
# ./build.sh all compile save # 编译+构建+导出所有
# ./build.sh gateway compile # 编译+构建 gateway
# ./build.sh serv save # 构建+导出所有后端
# ./build.sh web compile save # 编译+构建+导出前端
##############################################
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 "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
# 项目路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
PROJECT_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd)
DOCKER_DIR="${SCRIPT_DIR}"
BUILD_OUTPUT="${DOCKER_DIR}/output"
IMAGE_VERSION=$(date +%Y%m%d_%H%M%S)
# 服务列表
SERV_SERVICES="gateway system auth file ai workcase"
# 服务端口映射
declare -A SERVICE_PORTS=(
["gateway"]=8080
["system"]=8082
["auth"]=8081
["file"]=8084
["ai"]=8090
["workcase"]=8088
)
# 解析参数
BUILD_TARGET="${1:-all}"
shift || true
DO_COMPILE=false
DO_SAVE=false
SAVE_VERSION=""
for arg in "$@"; do
case $arg in
compile)
DO_COMPILE=true
;;
save)
DO_SAVE=true
;;
save=*)
DO_SAVE=true
SAVE_VERSION="${arg#save=}"
;;
esac
done
# 确定保存版本
if [ "${DO_SAVE}" = true ] && [ -z "${SAVE_VERSION}" ]; then
SAVE_VERSION="${IMAGE_VERSION}"
fi
echo "=========================================="
echo "Urban Lifeline - 构建脚本"
echo "=========================================="
log_info "构建目标: ${BUILD_TARGET}"
log_info "构建版本: ${IMAGE_VERSION}"
log_info "编译代码: ${DO_COMPILE}"
log_info "保存镜像: ${DO_SAVE}"
[ "${DO_SAVE}" = true ] && log_info "保存版本: ${SAVE_VERSION}"
echo "=========================================="
echo ""
mkdir -p "${BUILD_OUTPUT}"
# ================================================
# 编译函数
# ================================================
compile_serv_all() {
log_step "编译所有后端服务"
cd "${PROJECT_ROOT}/urbanLifelineServ"
mvn clean package -DskipTests
log_info "✅ 后端服务编译完成"
}
compile_serv_single() {
local service=$1
log_step "编译 ${service} 服务"
cd "${PROJECT_ROOT}/urbanLifelineServ"
mvn clean package -DskipTests -pl ${service} -am
log_info "${service} 服务编译完成"
}
compile_web() {
log_step "编译前端项目"
cd "${PROJECT_ROOT}/urbanLifelineWeb"
# 检查 pnpm
if command -v pnpm &> /dev/null; then
pnpm install
pnpm run build:all 2>/dev/null || {
# 如果没有 build:all 脚本,分别构建
log_info "分别构建各前端项目..."
cd packages/shared && pnpm run build && cd ../..
cd packages/platform && pnpm run build && cd ../..
cd packages/workcase && pnpm run build && cd ../..
}
else
npm install
npm run build:all 2>/dev/null || {
cd packages/shared && npm run build && cd ../..
cd packages/platform && npm run build && cd ../..
cd packages/workcase && npm run build && cd ../..
}
fi
log_info "✅ 前端项目编译完成"
}
# ================================================
# 构建函数
# ================================================
build_base() {
log_step "构建基础镜像"
cd "${PROJECT_ROOT}"
docker build \
-t urban-lifeline-base-serv:${IMAGE_VERSION} \
-t urban-lifeline-base-serv:latest \
-f docker/urbanLifeline/serv/Dockerfile.base .
log_info "✅ 基础镜像构建完成: urban-lifeline-base-serv:${IMAGE_VERSION}"
}
build_serv_single() {
local service=$1
local port=${SERVICE_PORTS[$service]}
log_step "构建 ${service} 服务镜像"
# 检查 JAR 包
local jar_file=$(find "${PROJECT_ROOT}/urbanLifelineServ/${service}/target" -name "*.jar" -type f 2>/dev/null | head -1)
if [ -z "$jar_file" ]; then
log_error "JAR 包不存在,请先编译: ./build.sh ${service} compile"
exit 1
fi
cd "${PROJECT_ROOT}"
docker build \
--build-arg SERVICE_NAME=${service} \
--build-arg SERVICE_PORT=${port} \
-t urban-lifeline-${service}:${IMAGE_VERSION} \
-t urban-lifeline-${service}:latest \
-f docker/urbanLifeline/serv/Dockerfile.template .
log_info "${service} 镜像构建完成: urban-lifeline-${service}:${IMAGE_VERSION}"
}
build_serv_all() {
for service in ${SERV_SERVICES}; do
build_serv_single ${service}
done
log_info "✅ 所有后端服务镜像构建完成"
}
build_web() {
build_platform
build_workcase_web
log_info "✅ 所有前端镜像构建完成"
}
build_platform() {
log_step "构建 platform 镜像"
if [ ! -d "${PROJECT_ROOT}/urbanLifelineWeb/packages/platform/dist" ]; then
log_error "platform dist 不存在,请先编译: ./build.sh platform compile"
exit 1
fi
cd "${PROJECT_ROOT}"
docker build \
--build-arg WEB_NAME=platform \
-t urban-lifeline-platform:${IMAGE_VERSION} \
-t urban-lifeline-platform:latest \
-f docker/urbanLifeline/web/Dockerfile .
log_info "✅ platform 镜像构建完成: urban-lifeline-platform:${IMAGE_VERSION}"
}
build_workcase_web() {
log_step "构建 workcase-web 镜像"
if [ ! -d "${PROJECT_ROOT}/urbanLifelineWeb/packages/workcase/dist" ]; then
log_error "workcase dist 不存在,请先编译: ./build.sh workcase-web compile"
exit 1
fi
cd "${PROJECT_ROOT}"
docker build \
--build-arg WEB_NAME=workcase \
-t urban-lifeline-workcase-web:${IMAGE_VERSION} \
-t urban-lifeline-workcase-web:latest \
-f docker/urbanLifeline/web/Dockerfile .
log_info "✅ workcase-web 镜像构建完成: urban-lifeline-workcase-web:${IMAGE_VERSION}"
}
# ================================================
# 导出函数
# ================================================
save_image() {
local image_name=$1
local version=${SAVE_VERSION}
local output_file="${BUILD_OUTPUT}/${image_name}_${version}.tar"
log_info "导出镜像: ${image_name}:${version}"
if ! docker images | grep -q "${image_name}.*${version}"; then
log_error "镜像不存在: ${image_name}:${version}"
return 1
fi
docker save -o "${output_file}" ${image_name}:${version}
local size=$(du -h "${output_file}" | cut -f1)
log_info "✅ 镜像已导出: ${output_file} (${size})"
}
save_serv_all() {
for service in ${SERV_SERVICES}; do
save_image "urban-lifeline-${service}"
done
}
# ================================================
# 主流程
# ================================================
main() {
# 编译
if [ "${DO_COMPILE}" = true ]; then
case ${BUILD_TARGET} in
base)
# 基础镜像不需要编译
;;
serv)
compile_serv_all
;;
web)
compile_web
;;
all)
compile_serv_all
compile_web
;;
gateway|system|auth|file|ai|workcase)
compile_serv_single ${BUILD_TARGET}
;;
*)
log_error "未知目标: ${BUILD_TARGET}"
exit 1
;;
esac
fi
# 构建镜像
case ${BUILD_TARGET} in
base)
build_base
;;
serv)
build_serv_all
;;
web)
build_web
;;
platform)
build_platform
;;
workcase-web)
build_workcase_web
;;
all)
# 检查基础镜像
if ! docker images | grep -q "urban-lifeline-base-serv.*latest"; then
log_warn "基础镜像不存在,先构建基础镜像"
build_base
fi
build_serv_all
build_web
;;
gateway|system|auth|file|ai|workcase)
build_serv_single ${BUILD_TARGET}
;;
*)
log_error "未知目标: ${BUILD_TARGET}"
echo ""
echo "可用目标: base, serv, web, all, gateway, system, auth, file, ai, workcase, platform, workcase-web"
exit 1
;;
esac
# 导出镜像
if [ "${DO_SAVE}" = true ]; then
case ${BUILD_TARGET} in
base)
save_image "urban-lifeline-base-serv"
;;
serv)
save_serv_all
;;
web)
save_image "urban-lifeline-platform"
save_image "urban-lifeline-workcase-web"
;;
platform)
save_image "urban-lifeline-platform"
;;
workcase-web)
save_image "urban-lifeline-workcase-web"
;;
all)
save_image "urban-lifeline-base-serv"
save_serv_all
save_image "urban-lifeline-platform"
save_image "urban-lifeline-workcase-web"
;;
gateway|system|auth|file|ai|workcase)
save_image "urban-lifeline-${BUILD_TARGET}"
;;
esac
echo ""
log_info "导出文件列表:"
ls -lh "${BUILD_OUTPUT}"/*.tar 2>/dev/null || true
fi
# 显示镜像列表
echo ""
log_info "Docker 镜像列表:"
docker images | grep "urban-lifeline" | head -20
echo ""
echo "=========================================="
log_info "✅ 构建完成!"
echo "=========================================="
}
main