diff --git a/00-init-tools.sh b/00-init-tools.sh index 6031643..7f5ea01 100755 --- a/00-init-tools.sh +++ b/00-init-tools.sh @@ -8,7 +8,7 @@ # 3. 安装 Node.js / npm(前端依赖) # 4. 安装 Docker(基础设施容器) # 5. 安装 etcdctl(查看 Etcd 服务注册) -# 6. 安装 Nginx 并写入 PC/CMS/Build-CMS/OpenIM 反代(本机 HTTP :80;外部 HTTPS 由 LB/CDN 终止) +# 6. 安装 Nginx 并写入 PC/CMS/Build-CMS/Build-Down/OpenIM 反代(本机 HTTP :80;外部 HTTPS 由 LB/CDN 终止) # 7. 写入 /etc/profile.d/deploy-env.sh(永久生效) # # 用法: @@ -309,10 +309,10 @@ _install_etcdctl() { } # ────────────────────────────────────────────────────────────────────────────── -# 6. Nginx — PC / CMS / Build-CMS / OpenIM 统一入口(本机 HTTP :80) +# 6. Nginx — PC / CMS / Build-CMS / Build-Down / OpenIM 统一入口(本机 HTTP :80) # ────────────────────────────────────────────────────────────────────────────── _install_pc_nginx_proxy() { - step "安装 Nginx 并配置 OpenIM/PC/CMS/Build-CMS 反代" + step "安装 Nginx 并配置 OpenIM/PC/CMS/Build-CMS/Build-Down 反代" if [[ "$(id -u)" -ne 0 ]]; then error " Nginx 安装需 root,请执行: sudo $0 nginx" @@ -374,12 +374,34 @@ _install_pc_nginx_proxy() { systemctl enable nginx 2>/dev/null || true systemctl restart nginx + local health_failed=0 + local host + for host in \ + "$proxy_domain" \ + "cms-jack.imharry.work" \ + "build-jack.imharry.work" \ + "down-jack.imharry.work" + do + if curl -fsS --max-time 3 -H "Host: ${host}" http://127.0.0.1/nginx-health >/dev/null 2>&1; then + success " Host 路由已生效: ${host}" + else + error " Host 路由检查失败: ${host}" + health_failed=1 + fi + done + success " Nginx 反代已启用(配置: $conf_src)" info " 本机 Nginx 仅监听 TCP 80;curl -sS -H 'Host: ${proxy_domain}' http://127.0.0.1/nginx-health 应返回 ok" info " 外部 HTTPS 可由 LB/CDN/其它网关终止后转发到本机 :80" - info " PC 入口: https://${proxy_domain}/" - info " CMS 入口: http://cms-jack.imharry.work/" - info " Build CMS 入口: http://build-jack.imharry.work/" + info " PC 入口: https://${proxy_domain}/" + info " CMS 入口: http://cms-jack.imharry.work/" + info " Build CMS 入口: http://build-jack.imharry.work/" + info " Build Down 入口: http://down-jack.imharry.work/" + + if [[ "$health_failed" -ne 0 ]]; then + error " Nginx 已重启,但部分 Host 路由校验失败,请检查 server_name / 默认站点 / 其它占用 :80 的配置" + return 1 + fi } # all 时非 root 则跳过(不中断 Go/Node/Docker/etcdctl) diff --git a/01-init-env.sh b/01-init-env.sh index 7383386..11a364a 100755 --- a/01-init-env.sh +++ b/01-init-env.sh @@ -104,10 +104,10 @@ CF_CUSTOMER_CODE=huonxouoa55ent9z TENCENT_SDK_APP_ID=20033091 TENCENT_SDK_SECRET_KEY=cceba44084aaa04f8c48a1858ffd5385875c3a5ec006d34278d9d3714b40e3b0 -# ── PC 客户端(Vite dev:web)对接的后端公网地址(可选)─────────────────────── +# ── PC 静态站点对接的后端公网地址(可选)────────────────────────────────────── # 通过域名访问 Nginx 反代(sudo ./deploy-test/00-init-tools.sh nginx)。 -# 填写 HTTPS 根地址,无末尾斜杠;Nginx 会将 / 代理到 pc dev:web :5173,并代理 API/WS。 -# ./deploy-test/07-start-frontend.sh 启动 pc 时会 export VITE_*,覆盖 pc/.env,无需改 pc 目录 +# 填写 HTTPS 根地址,无末尾斜杠;Nginx 会将 / 指向 /app/pc/dist,并代理 API/WS。 +# ./deploy-test/08-build-static-frontend.sh 构建 pc 时会 export VITE_*,覆盖 pc/.env,无需改 pc 目录 # 若某路径与网关不一致,可单独覆盖:PC_VITE_API_URL / PC_VITE_WS_URL / PC_VITE_CHAT_URL / PC_VITE_USER_URL PC_PROXY_DOMAIN=pc-jack.imharry.work PC_BACKEND_ORIGIN=https://pc-jack.imharry.work diff --git a/06-install-frontend.sh b/06-install-frontend.sh index d9d9444..071efe0 100755 --- a/06-install-frontend.sh +++ b/06-install-frontend.sh @@ -74,7 +74,9 @@ case "$TARGET" in success "所有前端依赖安装完成!" echo "" echo -e "${BOLD}下一步:${NC}" - echo -e " 启动前端开发服务器:" + echo -e " 构建静态前端(pc/cms/build-cms/build-down):" + echo -e " ${CYAN}./deploy-test/08-build-static-frontend.sh${NC}" + echo -e " 启动开发态前端(meetingh5/h5):" echo -e " ${CYAN}./deploy-test/07-start-frontend.sh${NC}" ;; pc|meetingh5|h5|cms|build-cms|build-down) diff --git a/07-start-frontend.sh b/07-start-frontend.sh index 9841e5a..ab1834b 100755 --- a/07-start-frontend.sh +++ b/07-start-frontend.sh @@ -1,20 +1,19 @@ #!/usr/bin/env bash # ============================================================================= -# 07-start-frontend.sh — 启动前端开发服务器 +# 07-start-frontend.sh — 启动前端开发服务器(开发态) # # 用法: # ./07-start-frontend.sh # 启动全部前端项目 # ./07-start-frontend.sh # 只启动指定项目 # # 项目与端口: -# pc → 默认 yarn dev:web :5173(无 Electron);本机要 Electron 时设 PC_ELECTRON=1 使用 yarn dev -# 后端地址:在 .env.deploy-test 设 PC_BACKEND_ORIGIN,启动时注入 VITE_*(不改 pc 目录) -# 域名入口由 Nginx 代理到 127.0.0.1:5173 -# meetingh5 → React + Vite :5188 +# meetingh5 → Vue + Vite :5188 # h5 → Vue + Vite :3003 -# cms → UMI Max :8001 -# build-cms → UMI Max :8002 -# build-down → UMI v3 :8003 +# +# +# 注意: +# pc / cms / build-cms / build-down 已改为静态构建 + Nginx 域名访问: +# ./deploy-test/08-build-static-frontend.sh # # 日志文件: .local-dev/logs/fe-.log # PID 文件: .local-dev/pids/fe-.pid @@ -41,66 +40,35 @@ header "启动前端开发服务器" # ── 前端服务配置 ────────────────────────────────────────────────────────────── # name → (目录, 包管理器, 启动命令, 环境变量, 端口描述) declare -A FE_DIR=( - [pc]="pc" [meetingh5]="meetingh5" [h5]="h5" - [cms]="cms" - [build-cms]="build-cms" - [build-down]="build-down" ) declare -A FE_PM=( - [pc]="yarn" [meetingh5]="npm" [h5]="npm" - [cms]="pnpm" - [build-cms]="pnpm" - [build-down]="npm" ) declare -A FE_CMD=( - [pc]="yarn dev:web" [meetingh5]="npm run dev" [h5]="npm run dev" - [cms]="./node_modules/.bin/max dev --host 0.0.0.0 --port 8001" - [build-cms]="./node_modules/.bin/max dev --host 0.0.0.0 --port 8002" - [build-down]="./node_modules/.bin/umi dev --host 0.0.0.0 --port 8003" ) -# cms/build-cms/build-down 不配置端口时默认都是 8000,需手动指定 declare -A FE_ENV=( - [pc]="" [meetingh5]="" [h5]="" - [cms]="REACT_APP_ENV=dev MOCK=none UMI_ENV=dev HOST=0.0.0.0 PORT=8001" - [build-cms]="MOCK=none UMI_ENV=dev HOST=0.0.0.0 PORT=8002" - [build-down]="NODE_OPTIONS=--openssl-legacy-provider HOST=0.0.0.0 PORT=8003" ) declare -A FE_PORT=( - [pc]=":5173 (yarn dev:web)" [meetingh5]=":5188" [h5]=":3003" - [cms]=":8001" - [build-cms]=":8002" - [build-down]=":8003" ) declare -A FE_PORT_NUM=( - [pc]="5173" [meetingh5]="5188" [h5]="3003" - [cms]="8001" - [build-cms]="8002" - [build-down]="8003" ) -# 本机需 Electron 桌面客户端时:PC_ELECTRON=1 → yarn dev(需 GUI / libatk 等) -if [[ "${PC_ELECTRON:-}" == "1" ]] || [[ "${PC_ELECTRON:-}" == "true" ]]; then - FE_CMD[pc]="yarn dev" - FE_PORT[pc]=":5173 (yarn dev + Electron)" -fi - _check_fe_port_free() { local name="$1" local port="${FE_PORT_NUM[$name]}" @@ -164,11 +132,6 @@ _start_fe() { # 已在运行 if [[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then warn "$name 已在运行 (端口=$port, PID=$(cat "$pidfile")),跳过" - if [[ "$name" == "pc" ]]; then - warn " Vite 环境变量只在启动时读取;若仍请求旧地址,请执行: ./deploy-test/stop-frontend.sh pc && ./deploy-test/07-start-frontend.sh pc" - pc_export_vite_backend_env - pc_print_vite_backend_env - fi return 0 fi @@ -191,13 +154,6 @@ _start_fe() { fi info "启动 ${BOLD}$name${NC} (端口=$port) ..." - if [[ "$name" == "pc" ]]; then - pc_ensure_wasm_assets - pc_export_vite_backend_env - pc_print_vite_backend_env - pc_check_nginx_gateway - fi - # 写日志分隔符 { echo "" @@ -207,9 +163,6 @@ _start_fe() { # 后台启动(带环境变量前缀) ( cd "$dir" - if [[ "$name" == "pc" ]]; then - pc_export_vite_backend_env - fi if [[ -n "$env_prefix" ]]; then # shellcheck disable=SC2086 nohup env $env_prefix $cmd >> "$logfile" 2>&1 & @@ -235,10 +188,6 @@ _start_fe() { return 1 fi success " ✓ $name (端口=$port, PID=$(cat "$pidfile")) ${FE_PORT[$name]} → $logfile" - if [[ "$name" == "pc" ]]; then - pc_check_wasm_assets "${PC_BACKEND_ORIGIN}" - info " PC 浏览器入口建议使用: ${PC_BACKEND_ORIGIN%/}/" - fi else error " ✗ $name 启动失败 (端口=$port),查看日志:" tail -20 "$logfile" 2>/dev/null || true @@ -248,7 +197,8 @@ _start_fe() { # ── 入口 ───────────────────────────────────────────────────────────────────── TARGET="${1:-all}" -FE_PROJECTS=(pc meetingh5 h5 cms build-cms build-down) +FE_PROJECTS=(meetingh5 h5) +STATIC_FRONTENDS=(pc cms build-cms build-down) _all_valid() { for p in "${FE_PROJECTS[@]}"; do @@ -279,11 +229,7 @@ if [[ "$TARGET" == "all" ]]; then echo "" echo -e "${BOLD}访问地址:${NC}" - echo " PC: ${PC_BACKEND_ORIGIN%/}/ (外部 HTTPS → 本机 Nginx :80 → pc dev:web :5173)" - echo " PC 直连调试: http://${DEPLOY_TEST_IP}:5173 (绕过 Nginx;Electron 用 PC_ELECTRON=1 或 pc 目录内 yarn dev)" echo " H5: http://${DEPLOY_TEST_IP}:3003" - echo " CMS: http://${DEPLOY_TEST_IP}:8001" - echo " Build CMS: http://${DEPLOY_TEST_IP}:8002" echo " Build Download: http://${DEPLOY_TEST_IP}:8003" echo "" echo -e "${BOLD}MeetingH5 访问地址(后端 URL 由 .env.local 默认设置,也可通过 URL 参数覆盖):${NC}" @@ -298,9 +244,18 @@ if [[ "$TARGET" == "all" ]]; then echo " 可能原因: node_modules 未安装,执行: ./deploy-test/06-install-frontend.sh" fi else + for static_fe in "${STATIC_FRONTENDS[@]}"; do + if [[ "$TARGET" == "$static_fe" ]]; then + error "$TARGET 已改为静态构建,不再通过 07-start-frontend.sh 启动" + echo "请执行: ./deploy-test/08-build-static-frontend.sh $TARGET" + echo "然后执行: sudo ./deploy-test/00-init-tools.sh nginx" + exit 1 + fi + done if ! _all_valid "$TARGET"; then error "未知项目: $TARGET" - echo "可用: ${FE_PROJECTS[*]}" + echo "开发态前端可用: ${FE_PROJECTS[*]}" + echo "静态前端请用: ./deploy-test/08-build-static-frontend.sh [pc|cms|build-cms|build-down]" exit 1 fi step "启动前端项目: $TARGET" diff --git a/08-build-static-frontend.sh b/08-build-static-frontend.sh old mode 100644 new mode 100755 index 2ac2461..c2e649a --- a/08-build-static-frontend.sh +++ b/08-build-static-frontend.sh @@ -1,55 +1,58 @@ #!/usr/bin/env bash # ============================================================================= -# 08-build-static-frontend.sh — 构建静态前端资源(dist) +# 08-build-static-frontend.sh — 构建静态前端产物(dist) # # 用法: -# ./08-build-static-frontend.sh # 构建 cms + build-cms -# ./08-build-static-frontend.sh cms # 只构建 cms -# ./08-build-static-frontend.sh build-cms # 只构建 build-cms +# ./08-build-static-frontend.sh # 构建全部静态前端 +# ./08-build-static-frontend.sh # 构建指定项目 # -# 产物目录: -# /app/cms/dist -# /app/build-cms/dist +# 可用项目: pc, cms, build-cms, build-down # ============================================================================= set -euo pipefail source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" init_dirs +load_env init_script_log -header "构建静态前端资源" +header "构建静态前端" -declare -A FE_DIR=( - [cms]="cms" - [build-cms]="build-cms" -) +STATIC_FRONTENDS=(pc cms build-cms build-down) declare -A FE_PM=( + [pc]="yarn" [cms]="pnpm" [build-cms]="pnpm" + [build-down]="npm" ) declare -A FE_BUILD_CMD=( + [pc]="yarn build" [cms]="pnpm run build" [build-cms]="pnpm run build" + [build-down]="npm run build" ) -FE_PROJECTS=(cms build-cms) -TARGET="${1:-all}" +declare -A FE_DIST_FILE=( + [pc]="$ROOT_DIR/pc/dist/index.html" + [cms]="$ROOT_DIR/cms/dist/index.html" + [build-cms]="$ROOT_DIR/build-cms/dist/index.html" + [build-down]="$ROOT_DIR/build-down/dist/index.html" +) -_valid_target() { - local target="$1" - for p in "${FE_PROJECTS[@]}"; do - [[ "$p" == "$target" ]] && return 0 - done - return 1 -} +declare -A FE_URL=( + [pc]="https://${PC_PROXY_DOMAIN:-pc-jack.imharry.work}/" + [cms]="http://cms-jack.imharry.work/" + [build-cms]="http://build-jack.imharry.work/" + [build-down]="http://down-jack.imharry.work/" +) -_build_fe() { +_build_one() { local name="$1" - local dir="$ROOT_DIR/${FE_DIR[$name]}" + local dir="$ROOT_DIR/$name" local pm="${FE_PM[$name]}" local cmd="${FE_BUILD_CMD[$name]}" - local dist_dir="$dir/dist" + local dist_file="${FE_DIST_FILE[$name]}" + local logfile="$LOG_DIR/build-${name}.log" if [[ ! -d "$dir" ]]; then error "$name 目录不存在: $dir" @@ -61,49 +64,70 @@ _build_fe() { return 1 fi - if ! command -v "$pm" &>/dev/null; then - error "$name 需要 $pm,未安装" + if ! command -v "$pm" >/dev/null 2>&1; then + error "$name 需要 $pm,但当前未安装" return 1 fi info "构建 ${BOLD}$name${NC} ..." + : > "$logfile" + + if [[ "$name" == "pc" ]]; then + pc_ensure_wasm_assets + pc_export_vite_backend_env + pc_print_vite_backend_env + fi + ( cd "$dir" - rm -rf "$dist_dir" # shellcheck disable=SC2086 - $cmd - ) + $cmd 2>&1 + ) | tee "$logfile" - if [[ ! -d "$dist_dir" ]]; then - error "$name 构建完成但 dist 不存在: $dist_dir" + if [[ ! -f "$dist_file" ]]; then + error "$name 构建完成,但未找到产物: $dist_file" return 1 fi - success "$name 构建完成 → $dist_dir" + success "$name 构建完成: $dist_file" + info "访问地址: ${FE_URL[$name]}" } +TARGET="${1:-all}" + if [[ "$TARGET" == "all" ]]; then FAILED=() - for proj in "${FE_PROJECTS[@]}"; do - _build_fe "$proj" || FAILED+=("$proj") + for project in "${STATIC_FRONTENDS[@]}"; do + if ! _build_one "$project"; then + FAILED+=("$project") + fi + echo "" done if [[ ${#FAILED[@]} -gt 0 ]]; then - error "以下静态前端构建失败: ${FAILED[*]}" + error "以下项目构建失败: ${FAILED[*]}" exit 1 fi else - if ! _valid_target "$TARGET"; then + valid=false + for project in "${STATIC_FRONTENDS[@]}"; do + if [[ "$TARGET" == "$project" ]]; then + valid=true + break + fi + done + + if ! $valid; then error "未知项目: $TARGET" - echo "可用: ${FE_PROJECTS[*]}" + echo "可用: ${STATIC_FRONTENDS[*]}" exit 1 fi - _build_fe "$TARGET" + + _build_one "$TARGET" fi echo "" -echo -e "${BOLD}下一步:${NC}" -echo " 1. 以 root 执行: sudo ./deploy-test/00-init-tools.sh nginx" -echo " 2. 域名访问:" -echo " - http://cms-jack.imharry.work/" -echo " - http://build-jack.imharry.work/" +success "静态前端构建完成" +echo "下一步:" +echo " sudo ./deploy-test/00-init-tools.sh nginx" +echo " ./deploy-test/09-verify-static-frontends.sh" diff --git a/09-verify-static-frontends.sh b/09-verify-static-frontends.sh new file mode 100644 index 0000000..533af43 --- /dev/null +++ b/09-verify-static-frontends.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +# ============================================================================= +# 09-verify-static-frontends.sh — 验证静态前端与 Nginx 域名入口 +# +# 用法: +# ./09-verify-static-frontends.sh +# +# 检查项: +# - /app/pc/dist / /app/cms/dist / /app/build-cms/dist / /app/build-down/dist 是否存在 +# - Nginx Host 路由是否可达 +# - 站点首页是否能返回 HTML +# ============================================================================= +set -euo pipefail +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" +init_dirs +init_script_log + +if [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck source=/dev/null + source "$ENV_FILE" + set +a +fi +normalize_pc_proxy_env + +require_tools curl + +header "验证静态前端" + +check_dist() { + local label="$1" path="$2" + if [[ -f "$path" ]]; then + success "$label dist 存在: $path" + else + error "$label dist 不存在: $path" + return 1 + fi +} + +check_site() { + local label="$1" host="$2" expected_path="$3" expected_title="${4:-}" + local body_file + local actual_title + body_file="$(mktemp)" + + if curl -fsS --max-time 5 -H "Host: ${host}" http://127.0.0.1/nginx-health >/dev/null 2>&1; then + success "$label nginx-health 可达: http://${host}/nginx-health" + else + error "$label nginx-health 不可达: http://${host}/nginx-health" + rm -f "$body_file" + return 1 + fi + + if curl -fsS --max-time 10 -H "Host: ${host}" http://127.0.0.1/ > "$body_file"; then + if grep -qi "[^<]*' "$body_file" | head -1 | sed -E 's###g' || true) + [[ -n "$actual_title" ]] && info " ${label} title: ${actual_title}" + info " ${label} dist: ${expected_path}" + if [[ -n "$expected_title" ]]; then + if [[ "$actual_title" == "$expected_title" ]]; then + success "$label title 符合预期" + else + error "$label title 不符合预期: 期望=${expected_title} 实际=${actual_title:-}" + rm -f "$body_file" + return 1 + fi + fi + else + error "$label 首页返回成功但不是 HTML: http://${host}/" + rm -f "$body_file" + return 1 + fi + else + error "$label 首页不可达: http://${host}/" + rm -f "$body_file" + return 1 + fi + + rm -f "$body_file" +} + +FAILED=() + +check_dist "PC" "$ROOT_DIR/pc/dist/index.html" || FAILED+=("pc-dist") +check_dist "CMS" "$ROOT_DIR/cms/dist/index.html" || FAILED+=("cms-dist") +check_dist "Build CMS" "$ROOT_DIR/build-cms/dist/index.html" || FAILED+=("build-cms-dist") +check_dist "Build Down" "$ROOT_DIR/build-down/dist/index.html" || FAILED+=("build-down-dist") + +check_site "PC" "${PC_PROXY_DOMAIN}" "$ROOT_DIR/pc/dist/index.html" || FAILED+=("pc-nginx") +check_site "CMS" "cms-jack.imharry.work" "$ROOT_DIR/cms/dist/index.html" "欢迎使用MChat" || FAILED+=("cms-nginx") +check_site "Build CMS" "build-jack.imharry.work" "$ROOT_DIR/build-cms/dist/index.html" "打包管理系统" || FAILED+=("build-cms-nginx") +check_site "Build Down" "down-jack.imharry.work" "$ROOT_DIR/build-down/dist/index.html" "下载" || FAILED+=("build-down-nginx") + +echo "" +pc_probe_msg_gateway "${PC_BACKEND_ORIGIN}" + +echo "" +if [[ ${#FAILED[@]} -eq 0 ]]; then + success "静态前端验证通过" +else + error "以下检查失败: ${FAILED[*]}" + exit 1 +fi diff --git a/README.md b/README.md index bf77141..1c66d7e 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,8 @@ deploy-test/ ./deploy-test/dt.sh stop # 停止 deploy-test 后端服务 ./deploy-test/dt.sh restart # 重启 deploy-test 后端服务 ./deploy-test/dt.sh status # 查看服务状态 -./deploy-test/dt.sh fe-start pc # 启动 pc 前端 +./deploy-test/dt.sh fe-build-static pc # 构建 pc 静态前端 +./deploy-test/dt.sh fe-verify-static # 验证静态前端域名入口 ./deploy-test/dt.sh fe-stop pc # 停止 pc 前端 ./deploy-test/dt.sh up # pull + build + restart ./deploy-test/dt.sh deploy # pull + build + restart + status @@ -181,13 +182,18 @@ vim .env.deploy-test # 7. 安装前端依赖(可选) ./deploy-test/06-install-frontend.sh -# 8. 启动前端开发服务器(可选) +# 8. 构建静态前端(pc/cms/build-cms/build-down,可选) +./deploy-test/08-build-static-frontend.sh + +# 9. 启动开发态前端(meetingh5/h5,可选) ./deploy-test/07-start-frontend.sh ``` > **pc(Electron)依赖安装**:**优先**按上文配置 **GitHub SSH 密钥**;裸机还需 **`00-init-tools.sh`**(见「步骤 0」)。若仍无法用 SSH,再依赖脚本内的 GitHub **HTTPS 重写**。详见「pc 前端 yarn install 失败」。`pc` 建议仅用 **Yarn**;可删除 `package-lock.json` 消除混用锁文件警告。 -> **`07-start-frontend.sh`**:启动前会读取 `.env.deploy-test`(若存在),文末「访问地址」等处使用 `DEPLOY_TEST_IP`;未设置时默认为 `127.0.0.1`,避免脚本在 `set -u` 下因未定义变量退出。 +> **`08-build-static-frontend.sh`**:构建前会读取 `.env.deploy-test`(若存在),其中 `pc` 会注入 `VITE_*` 并确保 wasm 资源存在。 +> +> **`07-start-frontend.sh`**:现在只用于 `meetingh5`、`h5` 这类开发态前端。 --- @@ -282,14 +288,23 @@ TENCENT_SDK_SECRET_KEY=xxx ### 前端开发服务器(可选) +**开发态前端** + | 项目 | 端口 | 说明 | |------|------|------| -| pc (Electron) | :7777 | Electron 桌面客户端 | | meetingh5 | :5188 | 直播观看 H5(弹幕+视频) | | h5 | :3003 | 移动端 H5 | -| cms | :8001 | 后台管理 | -| build-cms | :8002 | 构建管理后台 | -| build-down | :8003 | 下载页 | + +**静态站点** + +| 项目 | 访问地址 | 说明 | +|------|----------|------| +| pc | `https://pc-jack.imharry.work/` | Nginx -> `/app/pc/dist` | +| cms | `http://cms-jack.imharry.work/` | Nginx -> `/app/cms/dist` | +| build-cms | `http://build-jack.imharry.work/` | Nginx -> `/app/build-cms/dist` | +| build-down | `http://down-jack.imharry.work/` | Nginx -> `/app/build-down/dist` | + +> `pc`、`build-down` 在 `deploy-test` 中都按静态站点方式提供,不再通过 `07-start-frontend.sh` 起 Web dev server。若需要 Electron 桌面端调试,请进入 `pc/` 目录单独执行项目自身命令。 > **meetingh5 访问方式** > @@ -308,26 +323,56 @@ TENCENT_SDK_SECRET_KEY=xxx ### Nginx 反代(域名 HTTPS 入口,供 PC / 浏览器访问后端) -在**测试服务器**上部署 Nginx,本机 Nginx 仅监听 HTTP `:80`,统一反代 PC Vite dev:web server、OpenIM API、chat-api 与 MsgGateway WebSocket。外部访问仍使用 `https://pc-jack.imharry.work`,HTTPS 由外层 LB/CDN/其它网关终止后转发到本机 `:80`。 +在**测试服务器**上部署 Nginx,本机 Nginx 仅监听 HTTP `:80`,统一提供 PC/CMS/Build-CMS 的静态 `dist` 资源,并反代 OpenIM API、chat-api、admin-api、build-server 与 MsgGateway WebSocket。外部访问仍使用对应域名,HTTPS 可由外层 LB/CDN/其它网关终止后转发到本机 `:80`。 | 路径前缀 | 后端 | |----------|------| | `/api/im/` | `127.0.0.1:10002` | | `/api/user/`、`/api/chat/` | `127.0.0.1:10008` | | `/msg_gateway` | `127.0.0.1:10001`(WebSocket) | -| `/` | `127.0.0.1:5173`(PC Vite dev:web server) | +| `Host: pc-jack.imharry.work /` | `/app/pc/dist` | +| `Host: cms-jack.imharry.work /` | `/app/cms/dist` | +| `Host: build-jack.imharry.work /` | `/app/build-cms/dist` | +| `Host: down-jack.imharry.work /` | `/app/build-down/dist` | 1. 服务器上已执行 `05-start.sh` 等,保证 `10001/10002/10008` 在监听。 2. 域名 `pc-jack.imharry.work` 已解析到测试服务器公网 IP。 3. `.env.deploy-test` 中设置 **`PC_BACKEND_ORIGIN=https://pc-jack.imharry.work`**(无末尾 `/`)。 -4. 仓库根目录执行:`./deploy-test/07-start-frontend.sh pc` 或 `./deploy-test/dt.sh fe-start pc`,启动 PC Vite dev:web server。 -5. 仓库根目录执行:`sudo ./deploy-test/00-init-tools.sh nginx`(会安装 `nginx`,并写入配置 `deploy-test/nginx/openim-pc-proxy.conf`;亦已包含在 `00-init-tools.sh` 无参的 **all** 流程末尾,需 root)。 -6. 测试服务器本机/安全组放行 **TCP 80**;外层 LB/CDN/网关对公网提供 HTTPS `443` 并转发到本机 `80`。 -7. 浏览器打开 **`https://pc-jack.imharry.work/`**。 +4. 仓库根目录执行:`./deploy-test/08-build-static-frontend.sh pc` 或 `./deploy-test/dt.sh fe-build-static pc`,构建 PC 静态资源。 +5. 如需同时构建 PC / CMS / Build-CMS / Build-Down,可直接执行:`./deploy-test/08-build-static-frontend.sh`;也可分别构建单个项目。 +6. 仓库根目录执行:`sudo ./deploy-test/00-init-tools.sh nginx`(会安装 `nginx`,并写入配置 `deploy-test/nginx/openim-pc-proxy.conf`;亦已包含在 `00-init-tools.sh` 无参的 **all** 流程末尾,需 root)。 +7. 执行:`./deploy-test/09-verify-static-frontends.sh`,确认 `dist` 和域名入口都正常。 +8. 测试服务器本机/安全组放行 **TCP 80**;外层 LB/CDN/网关对公网提供 HTTPS `443` 并转发到本机 `80`。 +9. 浏览器打开 **`https://pc-jack.imharry.work/`**、**`http://cms-jack.imharry.work/`**、**`http://build-jack.imharry.work/`**、**`http://down-jack.imharry.work/`**。 -**域名访问**:本配置中 `openim-pc-proxy` 使用 `server_name pc-jack.imharry.work`,只监听本机 `80`;推荐外部 `GET /` 走 `https://pc-jack.imharry.work/`,由外层 HTTPS 入口转发到本机 `80` 后代理 PC Vite dev:web。`00-init-tools.sh nginx` 会禁用 `sites-enabled/default`,并尝试去掉 `sites-available/default` 里的 `default_server`,避免默认站点抢占 `:80`。若机上还有其它站点也写了 `default_server`,`nginx -t` 会报错,需在该站点配置中删除 `default_server`(保留 `listen 80;` 即可)。 +**推荐验收命令** -**PC dev:web**:`07-start-frontend.sh pc` 会在启动前注入 `VITE_API_URL`、`VITE_WS_URL`、`VITE_CHAT_URL`、`VITE_USER_URL` 等变量,并确保 `openIM.wasm`、`sql-wasm.wasm`、`wasm_exec.js` 存在于 `pc/public`。更新 `pc` 代码或 `.env.deploy-test` 后,需要重启 PC 前端:`./deploy-test/stop-frontend.sh pc && ./deploy-test/07-start-frontend.sh pc`。 +```bash +# 1. 构建全部静态前端 +./deploy-test/08-build-static-frontend.sh + +# 2. 安装 / 更新 nginx 配置并立即校验 Host 路由 +sudo ./deploy-test/00-init-tools.sh nginx + +# 3. 统一校验 dist / nginx-health / 首页 HTML / title +./deploy-test/09-verify-static-frontends.sh + +# 4. 查看当前状态(包含静态站点 title 摘要) +./deploy-test/status.sh + +# 5. 本机直连 nginx 做 Host 路由抽样 +curl -H 'Host: pc-jack.imharry.work' http://127.0.0.1/ | head +curl -H 'Host: cms-jack.imharry.work' http://127.0.0.1/ | head +curl -H 'Host: build-jack.imharry.work' http://127.0.0.1/ | head +curl -H 'Host: down-jack.imharry.work' http://127.0.0.1/ | head + +# 或者直接走一条命令(需 root / sudo) +sudo ./deploy-test/dt.sh fe-publish +``` + +**域名访问**:本配置中 `openim-pc-proxy` 使用 `server_name pc-jack.imharry.work`、`cms-jack.imharry.work`、`build-jack.imharry.work`、`down-jack.imharry.work`,只监听本机 `80`;推荐外部域名流量经 HTTPS 入口转发到本机 `80` 后由 Nginx 分发到对应静态站点与后端 API。`00-init-tools.sh nginx` 会禁用 `sites-enabled/default`,并尝试去掉 `sites-available/default` 里的 `default_server`,避免默认站点抢占 `:80`。若机上还有其它站点也写了 `default_server`,`nginx -t` 会报错,需在该站点配置中删除 `default_server`(保留 `listen 80;` 即可)。 + +**PC 静态构建**:`08-build-static-frontend.sh pc` 会在构建前注入 `VITE_API_URL`、`VITE_WS_URL`、`VITE_CHAT_URL`、`VITE_USER_URL` 等变量,并确保 `openIM.wasm`、`sql-wasm.wasm`、`wasm_exec.js` 存在于 `pc/public`。更新 `pc` 代码或 `.env.deploy-test` 后,需要重新构建:`./deploy-test/08-build-static-frontend.sh pc`。 ### Docker 基础设施 diff --git a/common.sh b/common.sh index e51903e..4a3098f 100755 --- a/common.sh +++ b/common.sh @@ -231,10 +231,15 @@ normalize_pc_proxy_env() { PC_PROXY_DOMAIN="${PC_PROXY_DOMAIN:-pc-jack.imharry.work}" local default_origin="https://${PC_PROXY_DOMAIN}" local origin="${PC_BACKEND_ORIGIN:-}" + local legacy_cms_origin="https://cms-jack.imharry.work" + local legacy_cms_origin_http="http://cms-jack.imharry.work" origin="${origin%/}" if [[ -z "$origin" ]]; then PC_BACKEND_ORIGIN="$default_origin" + elif [[ "$origin" == "$legacy_cms_origin" ]] || [[ "$origin" == "$legacy_cms_origin_http" ]]; then + warn " 检测到旧 PC_BACKEND_ORIGIN=${origin},已切换为 ${default_origin}" + PC_BACKEND_ORIGIN="$default_origin" elif [[ -n "${DEPLOY_TEST_IP:-}" ]] && [[ "$origin" =~ ^https?://${DEPLOY_TEST_IP}(:[0-9]+)?$ ]]; then warn " 检测到旧 PC_BACKEND_ORIGIN=${origin},已切换为 ${default_origin}" PC_BACKEND_ORIGIN="$default_origin" diff --git a/dt.sh b/dt.sh index 638b3c0..3533e33 100755 --- a/dt.sh +++ b/dt.sh @@ -46,8 +46,11 @@ deploy-test 后端/基础服务: status 调用 deploy-test/status.sh deploy-test 前端: - fe-start [project] 调用 deploy-test/07-start-frontend.sh [project] - fe-stop [project] 调用 deploy-test/stop-frontend.sh [project] + fe-start [project] 调用 deploy-test/07-start-frontend.sh [project](开发态前端) + fe-stop [project] 调用 deploy-test/stop-frontend.sh [project] + fe-build-static [project] 调用 deploy-test/08-build-static-frontend.sh [project](pc/cms/build-cms/build-down) + fe-verify-static 调用 deploy-test/09-verify-static-frontends.sh + fe-publish [project] 构建静态前端 + 更新 Nginx + 校验(默认 all) 常用组合: up pull + build + restart @@ -60,7 +63,9 @@ deploy-test 前端: ./deploy-test/dt.sh pull ./deploy-test/dt.sh build ./deploy-test/dt.sh restart - ./deploy-test/dt.sh fe-start pc + ./deploy-test/dt.sh fe-build-static pc + ./deploy-test/dt.sh fe-verify-static + sudo ./deploy-test/dt.sh fe-publish ./deploy-test/dt.sh deploy EOF } @@ -72,6 +77,14 @@ require_deploy_test() { fi } +require_root_for_publish() { + if [[ "$(id -u)" -ne 0 ]]; then + err "fe-publish 需要 root / sudo,因为会执行 nginx 安装与重载" + echo "请执行: sudo ./deploy-test/dt.sh fe-publish${1:+ $1}" + exit 1 + fi +} + run_deploy_test_script() { local script="$1" shift || true @@ -195,6 +208,27 @@ main() { fe-stop) run_deploy_test_script "stop-frontend.sh" "$@" ;; + fe-build-static) + run_deploy_test_script "08-build-static-frontend.sh" "$@" + ;; + fe-verify-static) + run_deploy_test_script "09-verify-static-frontends.sh" "$@" + ;; + fe-publish) + publish_target="${1:-all}" + require_root_for_publish "$publish_target" + run_deploy_test_script "08-build-static-frontend.sh" "$@" + run_deploy_test_script "00-init-tools.sh" nginx + run_deploy_test_script "09-verify-static-frontends.sh" + echo "" + ok "静态前端发布完成: ${publish_target}" + echo "已执行:" + echo " 1. 构建 dist" + echo " 2. 更新并重载 Nginx" + echo " 3. 校验静态站点入口" + echo "建议复查:" + echo " ./deploy-test/status.sh" + ;; up) update_all_repos run_deploy_test_script "04-build.sh" diff --git a/logs.sh b/logs.sh index 112d40d..36f2f2c 100755 --- a/logs.sh +++ b/logs.sh @@ -16,7 +16,8 @@ # # 后端服务: openim-server, chat-rpc, admin-rpc, chat-api, admin-api, # meetingmsg, livecloud, livestream, build-server -# 前端服务: pc, meetingh5, h5, cms, build-cms, build-down +# 前端服务: meetingh5, h5 +# 静态前端: pc, cms, build-cms, build-down(构建产物在 dist/,不通过本脚本查看 dev server 日志) # Docker: redis, kafka, etcd, livekit # ============================================================================= set -euo pipefail @@ -63,7 +64,7 @@ if [[ -z "$SVC" ]]; then echo "" echo -e "${BOLD}前端服务日志${NC} ($LOG_DIR/fe-*.log):" - FE_LIST=(pc meetingh5 h5 cms build-cms build-down) + FE_LIST=(meetingh5 h5) for fe in "${FE_LIST[@]}"; do fe_log="$LOG_DIR/fe-${fe}.log" if [[ -f "$fe_log" ]]; then @@ -146,7 +147,7 @@ case "$SVC" in esac # ── 前端服务日志 ────────────────────────────────────────────────────────────── -FE_LIST=(pc meetingh5 h5 cms build-cms build-down) +FE_LIST=(meetingh5 h5) for _fe in "${FE_LIST[@]}"; do if [[ "$SVC" == "$_fe" ]]; then LOGFILE="$LOG_DIR/fe-${SVC}.log" diff --git a/nginx/openim-pc-proxy.conf b/nginx/openim-pc-proxy.conf index c8bf8f4..a7a1048 100644 --- a/nginx/openim-pc-proxy.conf +++ b/nginx/openim-pc-proxy.conf @@ -8,7 +8,7 @@ # # CORS:chat-api(:10008)与 openim(:10001/:10002)已在应用内通过 openimsdk/tools/mw.CorsHandler # 返回 Access-Control-Allow-Origin: *。若在此再用 add_header 追加 $http_origin,浏览器会收到 -# 「*, http://IP:5173」两个值并报错。故本配置不在 Nginx 层添加 CORS,预检 OPTIONS 也交给上游处理。 +# 「*, http://IP」两个值并报错。故本配置不在 Nginx 层添加 CORS,预检 OPTIONS 也交给上游处理。 # # 推荐外部访问入口:https://pc-jack.imharry.work/ # 本 Nginx 仅监听 HTTP :80;HTTPS 由外层 LB/CDN/网关终止后转发到本机 :80。 @@ -110,20 +110,10 @@ server { return 200 "ok\n"; } - # PC Vite dev:web server. +# PC 静态站点(dist). location / { - proxy_pass http://127.0.0.1:5173; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; - proxy_buffering off; - proxy_read_timeout 86400s; - proxy_send_timeout 86400s; + root /app/pc/dist; + try_files $uri $uri/ /index.html; } } @@ -218,3 +208,27 @@ server { try_files $uri $uri/ /index.html; } } + +server { + listen 80; + listen [::]:80; + server_name down-jack.imharry.work; + + root /app/build-down/dist; + index index.html; + + access_log /var/log/nginx/openim-build-down-access.log openim_pc_gateway; + error_log /var/log/nginx/openim-build-down-error.log warn; + + client_max_body_size 100m; + + location = /nginx-health { + access_log off; + default_type text/plain; + return 200 "ok\n"; + } + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/pc-sdk-probe.sh b/pc-sdk-probe.sh index bf5e200..bf9ebc3 100755 --- a/pc-sdk-probe.sh +++ b/pc-sdk-probe.sh @@ -297,7 +297,7 @@ await window.__deployTestResetBrowserStorage() await window.__deployTestManualInitDB() 清理后按这个顺序重测: -1. 关闭其它 https://pc-jack.imharry.work/ / http://54.116.29.247:5173 标签页 +1. 关闭其它 https://pc-jack.imharry.work/ 标签页 2. 打开 https://pc-jack.imharry.work/ 并刷新页面 3. 重新粘贴本脚本输出的整段 JS(刷新会清掉已安装的 probe) 4. 再登录 diff --git a/setup.sh b/setup.sh index 70bd1af..fe4e9af 100755 --- a/setup.sh +++ b/setup.sh @@ -80,6 +80,10 @@ echo " ./deploy-test/logs.sh # 实时日志" echo " ./deploy-test/restart.sh # 重启服务" echo " ./deploy-test/restart.sh --build # 重编译并重启" echo " ./deploy-test/check-conn.sh # 验证 MongoDB / MinIO" +echo " ./deploy-test/08-build-static-frontend.sh # 构建 pc/cms/build-cms/build-down 静态资源" +echo " sudo ./deploy-test/dt.sh fe-publish # 构建静态前端 + 更新 Nginx + 校验" +echo " sudo ./deploy-test/00-init-tools.sh nginx # 安装 / 更新 Nginx 域名入口" +echo " ./deploy-test/09-verify-static-frontends.sh # 验证静态前端与域名入口" echo "" echo -e "${BOLD}停止服务:${NC}" echo " ./deploy-test/stop.sh # 停止后端进程" diff --git a/status.sh b/status.sh index 0729791..d204a85 100755 --- a/status.sh +++ b/status.sh @@ -148,28 +148,62 @@ if command -v curl &>/dev/null && [[ -n "${PC_BACKEND_ORIGIN:-}" ]]; then echo " PC Chat API: ${PC_VITE_CHAT_URL:-${PC_BACKEND_ORIGIN}/api/chat}" echo " PC Admin API: ${PC_VITE_ADMIN_URL:-${PC_BACKEND_ORIGIN}/api/admin}" echo " PC WebSocket: ${PC_VITE_WS_URL:-$default_ws_url}" - echo " PC 页面入口: ${PC_BACKEND_ORIGIN}/ (外部 HTTPS → 本机 Nginx :80 → pc dev:web :5173)" + echo " PC 页面入口: ${PC_BACKEND_ORIGIN}/ (外部 HTTPS → 本机 Nginx :80 → /app/pc/dist)" echo " Nginx 日志: /var/log/nginx/openim-pc-proxy-access.log" pc_probe_msg_gateway "$PC_BACKEND_ORIGIN" else printf " ${YELLOW}○${NC} %-14s %s\n" "nginx-health" "跳过(未安装 curl 或未设置 PC_BACKEND_ORIGIN)" fi -# ── 前端服务 ───────────────────────────────────────────────────────────────── +# ── 静态前端 ───────────────────────────────────────────────────────────────── +echo "" +echo -e "${BOLD}[ 静态前端 ]${NC}" +print_static_site_status() { + local label="$1" dist_file="$2" build_hint="$3" host_header="$4" access_url="$5" + local body title + + if [[ -f "$dist_file" ]]; then + printf " ${GREEN}●${NC} %-14s %s\n" "${label}-dist" "$dist_file" + else + printf " ${YELLOW}○${NC} %-14s %s\n" "${label}-dist" "未构建(执行 ${build_hint})" + fi + + if command -v curl &>/dev/null; then + if curl -fsS --max-time 3 -H "Host: ${host_header}" http://127.0.0.1/nginx-health >/dev/null 2>&1; then + printf " ${GREEN}●${NC} %-14s %s\n" "${label}-nginx" "$access_url" + body="$(curl -fsS --max-time 5 -H "Host: ${host_header}" http://127.0.0.1/ 2>/dev/null || true)" + if [[ -n "$body" ]] && printf '%s' "$body" | grep -qi "[^<]*' | head -1 | sed -E 's###g' || true)" + if [[ -n "$title" ]]; then + printf " ${CYAN}◉${NC} %-14s %s\n" "${label}-title" "$title" + else + printf " ${CYAN}◉${NC} %-14s %s\n" "${label}-title" "(未解析到 )" + fi + else + printf " ${YELLOW}○${NC} %-14s %s\n" "${label}-title" "首页返回异常,未识别为 HTML" + fi + else + printf " ${YELLOW}○${NC} %-14s %s\n" "${label}-nginx" "不可达(执行 sudo ./deploy-test/00-init-tools.sh nginx)" + fi + fi +} + +print_static_site_status "pc" "$ROOT_DIR/pc/dist/index.html" "./deploy-test/08-build-static-frontend.sh pc" "${PC_PROXY_DOMAIN}" "${PC_BACKEND_ORIGIN}/" +print_static_site_status "cms" "$ROOT_DIR/cms/dist/index.html" "./deploy-test/08-build-static-frontend.sh cms" "cms-jack.imharry.work" "http://cms-jack.imharry.work/" +print_static_site_status "build-cms" "$ROOT_DIR/build-cms/dist/index.html" "./deploy-test/08-build-static-frontend.sh build-cms" "build-jack.imharry.work" "http://build-jack.imharry.work/" +print_static_site_status "build-down" "$ROOT_DIR/build-down/dist/index.html" "./deploy-test/08-build-static-frontend.sh build-down" "down-jack.imharry.work" "http://down-jack.imharry.work/" + +# ── 前端开发服务器 ───────────────────────────────────────────────────────────── echo "" echo -e "${BOLD}[ 前端开发服务器 ]${NC}" fe_port_desc() { case "$1" in - pc) echo "5173 (yarn dev:web)" ;; meetingh5) echo "5188" ;; h5) echo "3003" ;; - cms) echo "8001" ;; - build-cms) echo "8002" ;; - build-down) echo "8003" ;; *) echo "?" ;; esac } -for fe in pc meetingh5 h5 cms build-cms build-down; do +for fe in meetingh5 h5; do pidfile="$PID_DIR/fe-${fe}.pid" logfile="$LOG_DIR/fe-${fe}.log" port_desc="$(fe_port_desc "$fe")" @@ -183,7 +217,7 @@ done # ── 端口占用检查 ────────────────────────────────────────────────────────────── echo "" echo -e "${BOLD}[ 端口占用 ]${NC}" -PORTS=(10002 10001 10008 10009 8000 8080 8888 8281 5173 5188 3003 8001 8002 8003) +PORTS=(10002 10001 10008 10009 8000 8080 8888 8281 5188 3003) for port in "${PORTS[@]}"; do pid=$(lsof -ti :"$port" 2>/dev/null | head -1 || true) if [[ -n "$pid" ]]; then @@ -197,10 +231,12 @@ done # ── 快速操作提示 ────────────────────────────────────────────────────────────── echo "" echo -e "${BOLD}[ 快捷命令 ]${NC}" -echo " ./deploy-test/logs.sh <service> 查看日志(支持前端: pc/h5/cms 等)" +echo " ./deploy-test/logs.sh <service> 查看日志(支持前端: meetingh5/h5)" echo " ./deploy-test/restart.sh <service> 重启后端服务" echo " ./deploy-test/restart.sh <svc> --build 重编译并重启" -echo " ./deploy-test/07-start-frontend.sh 启动前端服务" +echo " ./deploy-test/07-start-frontend.sh 启动开发态前端" +echo " ./deploy-test/08-build-static-frontend.sh 构建 pc/cms/build-cms/build-down 静态资源" +echo " sudo ./deploy-test/dt.sh fe-publish 构建静态前端 + 更新 Nginx + 校验" echo " ./deploy-test/stop-frontend.sh 停止前端服务" echo " ./deploy-test/check-conn.sh 验证 MongoDB/S3 连接" echo "" diff --git a/stop-frontend.sh b/stop-frontend.sh index 7e75bdf..f424a2a 100755 --- a/stop-frontend.sh +++ b/stop-frontend.sh @@ -6,23 +6,21 @@ # ./stop-frontend.sh # 停止全部前端服务 # ./stop-frontend.sh <project> # 只停止指定项目 # -# 可用项目: pc, meetingh5, h5, cms, build-cms, build-down +# 可用项目: meetingh5, h5 +# 注意: pc / cms / build-cms / build-down 已改为静态构建,不再通过本脚本管理 # ============================================================================= set -euo pipefail source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" init_dirs init_script_log # ← 脚本执行日志 -FE_PROJECTS=(pc meetingh5 h5 cms build-cms build-down) +FE_PROJECTS=(meetingh5 h5) +STATIC_FRONTENDS=(pc cms build-cms build-down) TARGET="${1:-all}" declare -A FE_PORT_NUM=( - [pc]="5173" [meetingh5]="5188" [h5]="3003" - [cms]="8001" - [build-cms]="8002" - [build-down]="8003" ) _stop_fe() { @@ -98,13 +96,20 @@ if [[ "$TARGET" == "all" ]]; then done success "所有前端服务已停止" else + for static_fe in "${STATIC_FRONTENDS[@]}"; do + if [[ "$TARGET" == "$static_fe" ]]; then + warn "$TARGET 已改为静态构建,没有前端开发服务器可停止" + echo "如需更新页面,请执行: ./deploy-test/08-build-static-frontend.sh $TARGET" + exit 0 + fi + done local_valid=false for p in "${FE_PROJECTS[@]}"; do [[ "$p" == "$TARGET" ]] && local_valid=true && break done if ! $local_valid; then error "未知项目: $TARGET" - echo "可用: ${FE_PROJECTS[*]}" + echo "开发态前端可用: ${FE_PROJECTS[*]}" exit 1 fi step "停止: $TARGET"