From 6c7e2e545c6020e963fdedf484460852903247c2 Mon Sep 17 00:00:00 2001 From: leiyun Date: Tue, 26 May 2026 22:47:27 +0800 Subject: [PATCH] =?UTF-8?q?fix=20:=20=E5=A4=84=E7=90=86=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- isolated/README.md | 16 ++++- isolated/build-package.ps1 | 60 +++++++++++++++-- isolated/build-package.sh | 82 ++++++++++++++++++----- isolated/dockerfiles/emp-admin.Dockerfile | 5 +- 4 files changed, 138 insertions(+), 25 deletions(-) diff --git a/isolated/README.md b/isolated/README.md index 1decc77..7e30df6 100644 --- a/isolated/README.md +++ b/isolated/README.md @@ -49,6 +49,21 @@ cd /path/to/emp/deploy/isolated sh build-package.sh ``` +如果 `deploy` 是独立仓库,不在 `emp` 根目录下,需要指定业务代码根目录: + +```bash +cd /home/git/emp_test_deploy/isolated +EMP_ROOT=/home/git/emp sh build-package.sh +``` + +`EMP_ROOT` 指向的目录下必须包含: + +```text +emp_server/ +emp_admin/ +emp_ws/ +``` + 如果本机已经构建好所有业务镜像,只想重新生成安装包: ```bash @@ -185,4 +200,3 @@ docker compose --env-file .env -f docker-compose.yml -p emp-test down ```bash docker compose --env-file .env -f docker-compose.yml -p emp-test down -v ``` - diff --git a/isolated/build-package.ps1 b/isolated/build-package.ps1 index d353430..5bd2244 100644 --- a/isolated/build-package.ps1 +++ b/isolated/build-package.ps1 @@ -2,6 +2,7 @@ param( [string]$ImageNamespace = $(if ($env:IMAGE_NAMESPACE) { $env:IMAGE_NAMESPACE } else { "emp-test" }), [string]$ImageTag = $(if ($env:IMAGE_TAG) { $env:IMAGE_TAG } else { Get-Date -Format "yyyyMMddHHmmss" }), [string]$NpmRegistry = $(if ($env:NPM_REGISTRY) { $env:NPM_REGISTRY } else { "https://registry.npmjs.org" }), + [string]$EmpRoot = $(if ($env:EMP_ROOT) { $env:EMP_ROOT } else { "" }), [switch]$SkipBuild, [switch]$NoMiddlewareImages ) @@ -10,8 +11,9 @@ $ErrorActionPreference = "Stop" # Local package script. Build images locally, export them, then run on server only with docker load + compose up. $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -$RootDir = Resolve-Path (Join-Path $ScriptDir "..\..") +$RootDir = $null $DistDir = Join-Path $ScriptDir "dist" +$BuildContextDir = Join-Path $ScriptDir ".build-context" $PackageName = "emp-test-runtime-$ImageTag" $PackageDir = Join-Path $DistDir $PackageName $PackageArchive = Join-Path $DistDir "$PackageName.tar.gz" @@ -75,6 +77,41 @@ function Assert-DockerDaemon { } } +function Test-EmpRoot { + param([string]$Path) + return (Test-Path (Join-Path $Path "emp_server")) ` + -and (Test-Path (Join-Path $Path "emp_admin")) ` + -and (Test-Path (Join-Path $Path "emp_ws")) +} + +function Resolve-EmpRoot { + if ($EmpRoot) { + $Resolved = (Resolve-Path $EmpRoot).Path + if (-not (Test-EmpRoot $Resolved)) { + throw "EMP_ROOT is invalid: $EmpRoot" + } + return $Resolved + } + + $Candidates = @( + (Join-Path $ScriptDir "..\.."), + (Join-Path $ScriptDir "..\..\emp"), + (Join-Path $ScriptDir ".."), + (Get-Location).Path + ) + + foreach ($Candidate in $Candidates) { + if (Test-Path $Candidate) { + $Resolved = (Resolve-Path $Candidate).Path + if (Test-EmpRoot $Resolved) { + return $Resolved + } + } + } + + throw "Cannot find EMP root. Set EMP_ROOT=/path/to/emp where emp_server, emp_admin and emp_ws exist." +} + function Invoke-Step { param( [string]$WorkingDirectory, @@ -120,9 +157,10 @@ function Build-JavaImages { function Build-WsImage { Write-Log "Build WS/simulator image" + $Dockerfile = Join-Path $ScriptDir "dockerfiles\emp-ws.Dockerfile" Invoke-Step $RootDir "docker" @( "build", - "-f", "deploy/isolated/dockerfiles/emp-ws.Dockerfile", + "-f", $Dockerfile, "--build-arg", "NPM_REGISTRY=$NpmRegistry", "-t", "$ImageNamespace/emp-ws:$ImageTag", "-t", "$ImageNamespace/emp-ws:latest", @@ -136,10 +174,20 @@ function Build-AdminImage { Invoke-Step $AdminDir "pnpm" @("install", "--frozen-lockfile") Invoke-Step $AdminDir "pnpm" @("run", "build:shunfeng") + Write-Log "Prepare frontend image context" + $ContextDir = Join-Path $BuildContextDir "emp-admin" + if (Test-Path $ContextDir) { + Remove-Item $ContextDir -Recurse -Force + } + New-Item -ItemType Directory -Force $ContextDir | Out-Null + Copy-Item (Join-Path $AdminDir "dist") (Join-Path $ContextDir "dist") -Recurse -Force + Copy-Item (Join-Path $ScriptDir "nginx\admin.conf") (Join-Path $ContextDir "admin.conf") -Force + Write-Log "Build frontend image" - Invoke-Step $RootDir "docker" @( + $Dockerfile = Join-Path $ScriptDir "dockerfiles\emp-admin.Dockerfile" + Invoke-Step $ContextDir "docker" @( "build", - "-f", "deploy/isolated/dockerfiles/emp-admin.Dockerfile", + "-f", $Dockerfile, "-t", "$ImageNamespace/emp-admin:$ImageTag", "-t", "$ImageNamespace/emp-admin:latest", "." @@ -190,6 +238,10 @@ Assert-Command "docker" Assert-DockerDaemon Assert-Command "tar" +$RootDir = Resolve-EmpRoot +Write-Log "EMP root: $RootDir" +Write-Log "Deploy root: $ScriptDir" + if (-not $SkipBuild) { Assert-Command "mvn" Assert-Command "pnpm" diff --git a/isolated/build-package.sh b/isolated/build-package.sh index d5203e1..7d3ded7 100644 --- a/isolated/build-package.sh +++ b/isolated/build-package.sh @@ -1,10 +1,14 @@ #!/usr/bin/env bash set -Eeuo pipefail -# 本地打包脚本:本机完成构建和 docker save,服务器只需要 docker load + compose up。 +# Build all images locally, export them, and create a server runtime package. +# Supports both layouts: +# 1. monorepo: emp/deploy/isolated/build-package.sh +# 2. split deploy: emp_test_deploy/isolated/build-package.sh with EMP_ROOT=/path/to/emp + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" DIST_DIR="$SCRIPT_DIR/dist" +BUILD_CONTEXT_DIR="$SCRIPT_DIR/.build-context" IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-emp-test}" IMAGE_TAG="${IMAGE_TAG:-$(date '+%Y%m%d%H%M%S')}" @@ -51,35 +55,71 @@ die() { } need_cmd() { - command -v "$1" >/dev/null 2>&1 || die "缺少命令:$1" + command -v "$1" >/dev/null 2>&1 || die "Missing command: $1" +} + +has_emp_root() { + [[ -d "$1/emp_server" && -d "$1/emp_admin" && -d "$1/emp_ws" ]] +} + +resolve_root_dir() { + if [[ -n "${EMP_ROOT:-}" ]]; then + local root + root="$(cd "$EMP_ROOT" && pwd)" + has_emp_root "$root" || die "EMP_ROOT is invalid: $EMP_ROOT" + printf '%s\n' "$root" + return + fi + + local candidates=( + "$SCRIPT_DIR/../.." + "$SCRIPT_DIR/../../emp" + "$SCRIPT_DIR/.." + "$PWD" + ) + local candidate root + for candidate in "${candidates[@]}"; do + if [[ -d "$candidate" ]]; then + root="$(cd "$candidate" && pwd)" + if has_emp_root "$root"; then + printf '%s\n' "$root" + return + fi + fi + done + + die "Cannot find EMP root. Set EMP_ROOT=/path/to/emp where emp_server, emp_admin and emp_ws exist." } +ROOT_DIR="$(resolve_root_dir)" + build_java_images() { cd "$ROOT_DIR/emp_server" - log "构建后端 jar" + log "Build backend jars" mvn package -DskipTests -B -pl "$(IFS=,; echo "${JAVA_MODULES[*]}")" -am for module in "${JAVA_MODULES[@]}"; do local jar jar="$(ls "$module"/target/*.jar | grep -v original | grep -v app.jar | head -1)" + [[ -n "$jar" ]] || die "Jar not found for $module" cp "$jar" "$module/target/app.jar" done - log "构建后端镜像" + log "Build backend images" docker build -f Dockerfile.service --build-arg MODULE=emp_gateway -t "$IMAGE_NAMESPACE/emp-gateway:$IMAGE_TAG" -t "$IMAGE_NAMESPACE/emp-gateway:latest" . docker build -f Dockerfile.service --build-arg MODULE=emp_auth -t "$IMAGE_NAMESPACE/emp-auth:$IMAGE_TAG" -t "$IMAGE_NAMESPACE/emp-auth:latest" . docker build -f Dockerfile.service --build-arg MODULE=emp_monitor -t "$IMAGE_NAMESPACE/emp-monitor:$IMAGE_TAG" -t "$IMAGE_NAMESPACE/emp-monitor:latest" . docker build -f Dockerfile.service --build-arg MODULE=emp_data -t "$IMAGE_NAMESPACE/emp-data:$IMAGE_TAG" -t "$IMAGE_NAMESPACE/emp-data:latest" . - log "构建 PDF 镜像" + log "Build PDF image" docker build -f emp_pdf/Dockerfile -t "$IMAGE_NAMESPACE/emp-pdf:$IMAGE_TAG" -t "$IMAGE_NAMESPACE/emp-pdf:latest" emp_pdf } build_ws_image() { cd "$ROOT_DIR" - log "构建 WS/模拟器镜像" + log "Build WS/simulator image" docker build \ - -f deploy/isolated/dockerfiles/emp-ws.Dockerfile \ + -f "$SCRIPT_DIR/dockerfiles/emp-ws.Dockerfile" \ --build-arg "NPM_REGISTRY=$NPM_REGISTRY" \ -t "$IMAGE_NAMESPACE/emp-ws:$IMAGE_TAG" \ -t "$IMAGE_NAMESPACE/emp-ws:latest" \ @@ -88,17 +128,22 @@ build_ws_image() { build_admin_image() { cd "$ROOT_DIR/emp_admin" - log "构建前端 dist" + log "Build frontend dist" pnpm install --frozen-lockfile pnpm run build:shunfeng - cd "$ROOT_DIR" - log "构建前端镜像" + log "Prepare frontend image context" + rm -rf "$BUILD_CONTEXT_DIR/emp-admin" + mkdir -p "$BUILD_CONTEXT_DIR/emp-admin" + cp -R "$ROOT_DIR/emp_admin/dist" "$BUILD_CONTEXT_DIR/emp-admin/dist" + cp "$SCRIPT_DIR/nginx/admin.conf" "$BUILD_CONTEXT_DIR/emp-admin/admin.conf" + + log "Build frontend image" docker build \ - -f deploy/isolated/dockerfiles/emp-admin.Dockerfile \ + -f "$SCRIPT_DIR/dockerfiles/emp-admin.Dockerfile" \ -t "$IMAGE_NAMESPACE/emp-admin:$IMAGE_TAG" \ -t "$IMAGE_NAMESPACE/emp-admin:latest" \ - . + "$BUILD_CONTEXT_DIR/emp-admin" } prepare_package() { @@ -117,14 +162,14 @@ save_images() { local images=("${APP_IMAGES[@]}") if [[ "$INCLUDE_MIDDLEWARE_IMAGES" == "1" ]]; then - log "拉取中间件镜像" + log "Pull middleware images" for image in "${MIDDLEWARE_IMAGES[@]}"; do docker pull "$image" images+=("$image") done fi - log "导出镜像包" + log "Save images" docker save -o "$PACKAGE_DIR/images.tar" "${images[@]}" } @@ -132,12 +177,15 @@ archive_package() { mkdir -p "$DIST_DIR" rm -f "$PACKAGE_ARCHIVE" tar -czf "$PACKAGE_ARCHIVE" -C "$DIST_DIR" "$PACKAGE_NAME" - log "打包完成:$PACKAGE_ARCHIVE" + log "Package created: $PACKAGE_ARCHIVE" } need_cmd docker need_cmd tar +log "EMP root: $ROOT_DIR" +log "Deploy root: $SCRIPT_DIR" + if [[ "$SKIP_BUILD" != "1" ]]; then need_cmd mvn need_cmd pnpm @@ -145,7 +193,7 @@ if [[ "$SKIP_BUILD" != "1" ]]; then build_ws_image build_admin_image else - log "跳过构建,仅打包当前本机已有镜像" + log "Skip build, package existing local images only" fi prepare_package diff --git a/isolated/dockerfiles/emp-admin.Dockerfile b/isolated/dockerfiles/emp-admin.Dockerfile index 7d5e536..792a206 100644 --- a/isolated/dockerfiles/emp-admin.Dockerfile +++ b/isolated/dockerfiles/emp-admin.Dockerfile @@ -1,7 +1,6 @@ FROM nginx:alpine -COPY emp_admin/dist /usr/share/nginx/html -COPY deploy/isolated/nginx/admin.conf /etc/nginx/conf.d/default.conf +COPY dist /usr/share/nginx/html +COPY admin.conf /etc/nginx/conf.d/default.conf EXPOSE 80 -