This commit is contained in:
vet
2026-04-21 12:24:04 +07:00
parent 67ab5f5ba5
commit 6eb89ad2a9
15 changed files with 421 additions and 170 deletions

View File

@@ -8,7 +8,7 @@
# 3. 安装 Node.js / npm前端依赖 # 3. 安装 Node.js / npm前端依赖
# 4. 安装 Docker基础设施容器 # 4. 安装 Docker基础设施容器
# 5. 安装 etcdctl查看 Etcd 服务注册) # 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永久生效 # 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() { _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 if [[ "$(id -u)" -ne 0 ]]; then
error " Nginx 安装需 root请执行: sudo $0 nginx" error " Nginx 安装需 root请执行: sudo $0 nginx"
@@ -374,12 +374,34 @@ _install_pc_nginx_proxy() {
systemctl enable nginx 2>/dev/null || true systemctl enable nginx 2>/dev/null || true
systemctl restart nginx 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" success " Nginx 反代已启用(配置: $conf_src"
info " 本机 Nginx 仅监听 TCP 80curl -sS -H 'Host: ${proxy_domain}' http://127.0.0.1/nginx-health 应返回 ok" info " 本机 Nginx 仅监听 TCP 80curl -sS -H 'Host: ${proxy_domain}' http://127.0.0.1/nginx-health 应返回 ok"
info " 外部 HTTPS 可由 LB/CDN/其它网关终止后转发到本机 :80" info " 外部 HTTPS 可由 LB/CDN/其它网关终止后转发到本机 :80"
info " PC 入口: https://${proxy_domain}/" info " PC 入口: https://${proxy_domain}/"
info " CMS 入口: http://cms-jack.imharry.work/" info " CMS 入口: http://cms-jack.imharry.work/"
info " Build CMS 入口: http://build-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 # all 时非 root 则跳过(不中断 Go/Node/Docker/etcdctl

View File

@@ -104,10 +104,10 @@ CF_CUSTOMER_CODE=huonxouoa55ent9z
TENCENT_SDK_APP_ID=20033091 TENCENT_SDK_APP_ID=20033091
TENCENT_SDK_SECRET_KEY=cceba44084aaa04f8c48a1858ffd5385875c3a5ec006d34278d9d3714b40e3b0 TENCENT_SDK_SECRET_KEY=cceba44084aaa04f8c48a1858ffd5385875c3a5ec006d34278d9d3714b40e3b0
# ── PC 客户端Vite dev:web对接的后端公网地址可选─────────────────────── # ── PC 静态站点对接的后端公网地址(可选)──────────────────────────────────────
# 通过域名访问 Nginx 反代sudo ./deploy-test/00-init-tools.sh nginx # 通过域名访问 Nginx 反代sudo ./deploy-test/00-init-tools.sh nginx
# 填写 HTTPS 根地址无末尾斜杠Nginx 会将 / 代理到 pc dev:web :5173,并代理 API/WS。 # 填写 HTTPS 根地址无末尾斜杠Nginx 会将 / 指向 /app/pc/dist,并代理 API/WS。
# ./deploy-test/07-start-frontend.sh 启动 pc 时会 export VITE_*,覆盖 pc/.env无需改 pc 目录 # ./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_VITE_API_URL / PC_VITE_WS_URL / PC_VITE_CHAT_URL / PC_VITE_USER_URL
PC_PROXY_DOMAIN=pc-jack.imharry.work PC_PROXY_DOMAIN=pc-jack.imharry.work
PC_BACKEND_ORIGIN=https://pc-jack.imharry.work PC_BACKEND_ORIGIN=https://pc-jack.imharry.work

View File

@@ -74,7 +74,9 @@ case "$TARGET" in
success "所有前端依赖安装完成!" success "所有前端依赖安装完成!"
echo "" echo ""
echo -e "${BOLD}下一步:${NC}" 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}" echo -e " ${CYAN}./deploy-test/07-start-frontend.sh${NC}"
;; ;;
pc|meetingh5|h5|cms|build-cms|build-down) pc|meetingh5|h5|cms|build-cms|build-down)

View File

@@ -1,20 +1,19 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# ============================================================================= # =============================================================================
# 07-start-frontend.sh — 启动前端开发服务器 # 07-start-frontend.sh — 启动前端开发服务器(开发态)
# #
# 用法: # 用法:
# ./07-start-frontend.sh # 启动全部前端项目 # ./07-start-frontend.sh # 启动全部前端项目
# ./07-start-frontend.sh <project> # 只启动指定项目 # ./07-start-frontend.sh <project> # 只启动指定项目
# #
# 项目与端口: # 项目与端口:
# pc → 默认 yarn dev:web :5173无 Electron本机要 Electron 时设 PC_ELECTRON=1 使用 yarn dev # meetingh5 → Vue + Vite :5188
# 后端地址:在 .env.deploy-test 设 PC_BACKEND_ORIGIN启动时注入 VITE_*(不改 pc 目录)
# 域名入口由 Nginx 代理到 127.0.0.1:5173
# meetingh5 → React + Vite :5188
# h5 → Vue + Vite :3003 # 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-<project>.log # 日志文件: .local-dev/logs/fe-<project>.log
# PID 文件: .local-dev/pids/fe-<project>.pid # PID 文件: .local-dev/pids/fe-<project>.pid
@@ -41,66 +40,35 @@ header "启动前端开发服务器"
# ── 前端服务配置 ────────────────────────────────────────────────────────────── # ── 前端服务配置 ──────────────────────────────────────────────────────────────
# name → (目录, 包管理器, 启动命令, 环境变量, 端口描述) # name → (目录, 包管理器, 启动命令, 环境变量, 端口描述)
declare -A FE_DIR=( declare -A FE_DIR=(
[pc]="pc"
[meetingh5]="meetingh5" [meetingh5]="meetingh5"
[h5]="h5" [h5]="h5"
[cms]="cms"
[build-cms]="build-cms"
[build-down]="build-down"
) )
declare -A FE_PM=( declare -A FE_PM=(
[pc]="yarn"
[meetingh5]="npm" [meetingh5]="npm"
[h5]="npm" [h5]="npm"
[cms]="pnpm"
[build-cms]="pnpm"
[build-down]="npm"
) )
declare -A FE_CMD=( declare -A FE_CMD=(
[pc]="yarn dev:web"
[meetingh5]="npm run dev" [meetingh5]="npm run dev"
[h5]="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=( declare -A FE_ENV=(
[pc]=""
[meetingh5]="" [meetingh5]=""
[h5]="" [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=( declare -A FE_PORT=(
[pc]=":5173 (yarn dev:web)"
[meetingh5]=":5188" [meetingh5]=":5188"
[h5]=":3003" [h5]=":3003"
[cms]=":8001"
[build-cms]=":8002"
[build-down]=":8003"
) )
declare -A FE_PORT_NUM=( declare -A FE_PORT_NUM=(
[pc]="5173"
[meetingh5]="5188" [meetingh5]="5188"
[h5]="3003" [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() { _check_fe_port_free() {
local name="$1" local name="$1"
local port="${FE_PORT_NUM[$name]}" local port="${FE_PORT_NUM[$name]}"
@@ -164,11 +132,6 @@ _start_fe() {
# 已在运行 # 已在运行
if [[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then if [[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then
warn "$name 已在运行 (端口=$port, PID=$(cat "$pidfile")),跳过" 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 return 0
fi fi
@@ -191,13 +154,6 @@ _start_fe() {
fi fi
info "启动 ${BOLD}$name${NC} (端口=$port) ..." 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 "" echo ""
@@ -207,9 +163,6 @@ _start_fe() {
# 后台启动(带环境变量前缀) # 后台启动(带环境变量前缀)
( (
cd "$dir" cd "$dir"
if [[ "$name" == "pc" ]]; then
pc_export_vite_backend_env
fi
if [[ -n "$env_prefix" ]]; then if [[ -n "$env_prefix" ]]; then
# shellcheck disable=SC2086 # shellcheck disable=SC2086
nohup env $env_prefix $cmd >> "$logfile" 2>&1 & nohup env $env_prefix $cmd >> "$logfile" 2>&1 &
@@ -235,10 +188,6 @@ _start_fe() {
return 1 return 1
fi fi
success "$name (端口=$port, PID=$(cat "$pidfile")) ${FE_PORT[$name]}$logfile" 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 else
error "$name 启动失败 (端口=$port),查看日志:" error "$name 启动失败 (端口=$port),查看日志:"
tail -20 "$logfile" 2>/dev/null || true tail -20 "$logfile" 2>/dev/null || true
@@ -248,7 +197,8 @@ _start_fe() {
# ── 入口 ───────────────────────────────────────────────────────────────────── # ── 入口 ─────────────────────────────────────────────────────────────────────
TARGET="${1:-all}" 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() { _all_valid() {
for p in "${FE_PROJECTS[@]}"; do for p in "${FE_PROJECTS[@]}"; do
@@ -279,11 +229,7 @@ if [[ "$TARGET" == "all" ]]; then
echo "" echo ""
echo -e "${BOLD}访问地址:${NC}" echo -e "${BOLD}访问地址:${NC}"
echo " PC: ${PC_BACKEND_ORIGIN%/}/ (外部 HTTPS → 本机 Nginx :80 → pc dev:web :5173)"
echo " PC 直连调试: http://${DEPLOY_TEST_IP}:5173 (绕过 NginxElectron 用 PC_ELECTRON=1 或 pc 目录内 yarn dev)"
echo " H5: http://${DEPLOY_TEST_IP}:3003" 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 " Build Download: http://${DEPLOY_TEST_IP}:8003"
echo "" echo ""
echo -e "${BOLD}MeetingH5 访问地址(后端 URL 由 .env.local 默认设置,也可通过 URL 参数覆盖):${NC}" 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" echo " 可能原因: node_modules 未安装,执行: ./deploy-test/06-install-frontend.sh"
fi fi
else 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 if ! _all_valid "$TARGET"; then
error "未知项目: $TARGET" error "未知项目: $TARGET"
echo "可用: ${FE_PROJECTS[*]}" echo "开发态前端可用: ${FE_PROJECTS[*]}"
echo "静态前端请用: ./deploy-test/08-build-static-frontend.sh [pc|cms|build-cms|build-down]"
exit 1 exit 1
fi fi
step "启动前端项目: $TARGET" step "启动前端项目: $TARGET"

110
08-build-static-frontend.sh Normal file → Executable file
View File

@@ -1,55 +1,58 @@
#!/usr/bin/env bash #!/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 # 构建全部静态前端
# ./08-build-static-frontend.sh cms # 构建 cms # ./08-build-static-frontend.sh <project> # 构建指定项目
# ./08-build-static-frontend.sh build-cms # 只构建 build-cms
# #
# 产物目录: # 可用项目: pc, cms, build-cms, build-down
# /app/cms/dist
# /app/build-cms/dist
# ============================================================================= # =============================================================================
set -euo pipefail set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
init_dirs init_dirs
load_env
init_script_log init_script_log
header "构建静态前端资源" header "构建静态前端"
declare -A FE_DIR=( STATIC_FRONTENDS=(pc cms build-cms build-down)
[cms]="cms"
[build-cms]="build-cms"
)
declare -A FE_PM=( declare -A FE_PM=(
[pc]="yarn"
[cms]="pnpm" [cms]="pnpm"
[build-cms]="pnpm" [build-cms]="pnpm"
[build-down]="npm"
) )
declare -A FE_BUILD_CMD=( declare -A FE_BUILD_CMD=(
[pc]="yarn build"
[cms]="pnpm run build" [cms]="pnpm run build"
[build-cms]="pnpm run build" [build-cms]="pnpm run build"
[build-down]="npm run build"
) )
FE_PROJECTS=(cms build-cms) declare -A FE_DIST_FILE=(
TARGET="${1:-all}" [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() { declare -A FE_URL=(
local target="$1" [pc]="https://${PC_PROXY_DOMAIN:-pc-jack.imharry.work}/"
for p in "${FE_PROJECTS[@]}"; do [cms]="http://cms-jack.imharry.work/"
[[ "$p" == "$target" ]] && return 0 [build-cms]="http://build-jack.imharry.work/"
done [build-down]="http://down-jack.imharry.work/"
return 1 )
}
_build_fe() { _build_one() {
local name="$1" local name="$1"
local dir="$ROOT_DIR/${FE_DIR[$name]}" local dir="$ROOT_DIR/$name"
local pm="${FE_PM[$name]}" local pm="${FE_PM[$name]}"
local cmd="${FE_BUILD_CMD[$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 if [[ ! -d "$dir" ]]; then
error "$name 目录不存在: $dir" error "$name 目录不存在: $dir"
@@ -61,49 +64,70 @@ _build_fe() {
return 1 return 1
fi fi
if ! command -v "$pm" &>/dev/null; then if ! command -v "$pm" >/dev/null 2>&1; then
error "$name 需要 $pm,未安装" error "$name 需要 $pm但当前未安装"
return 1 return 1
fi fi
info "构建 ${BOLD}$name${NC} ..." 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" cd "$dir"
rm -rf "$dist_dir"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
$cmd $cmd 2>&1
) ) | tee "$logfile"
if [[ ! -d "$dist_dir" ]]; then if [[ ! -f "$dist_file" ]]; then
error "$name 构建完成但 dist 不存在: $dist_dir" error "$name 构建完成,但未找到产物: $dist_file"
return 1 return 1
fi fi
success "$name 构建完成 $dist_dir" success "$name 构建完成: $dist_file"
info "访问地址: ${FE_URL[$name]}"
} }
TARGET="${1:-all}"
if [[ "$TARGET" == "all" ]]; then if [[ "$TARGET" == "all" ]]; then
FAILED=() FAILED=()
for proj in "${FE_PROJECTS[@]}"; do for project in "${STATIC_FRONTENDS[@]}"; do
_build_fe "$proj" || FAILED+=("$proj") if ! _build_one "$project"; then
FAILED+=("$project")
fi
echo ""
done done
if [[ ${#FAILED[@]} -gt 0 ]]; then if [[ ${#FAILED[@]} -gt 0 ]]; then
error "以下静态前端构建失败: ${FAILED[*]}" error "以下项目构建失败: ${FAILED[*]}"
exit 1 exit 1
fi fi
else 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" error "未知项目: $TARGET"
echo "可用: ${FE_PROJECTS[*]}" echo "可用: ${STATIC_FRONTENDS[*]}"
exit 1 exit 1
fi fi
_build_fe "$TARGET"
_build_one "$TARGET"
fi fi
echo "" echo ""
echo -e "${BOLD}下一步:${NC}" success "静态前端构建完成"
echo " 1. 以 root 执行: sudo ./deploy-test/00-init-tools.sh nginx" echo "下一步:"
echo " 2. 域名访问:" echo " sudo ./deploy-test/00-init-tools.sh nginx"
echo " - http://cms-jack.imharry.work/" echo " ./deploy-test/09-verify-static-frontends.sh"
echo " - http://build-jack.imharry.work/"

View File

@@ -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 "<html" "$body_file"; then
success "$label 首页可达: http://${host}/"
actual_title=$(grep -oiE '<title>[^<]*</title>' "$body_file" | head -1 | sed -E 's#</?title>##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:-<empty>}"
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

View File

@@ -103,7 +103,8 @@ deploy-test/
./deploy-test/dt.sh stop # 停止 deploy-test 后端服务 ./deploy-test/dt.sh stop # 停止 deploy-test 后端服务
./deploy-test/dt.sh restart # 重启 deploy-test 后端服务 ./deploy-test/dt.sh restart # 重启 deploy-test 后端服务
./deploy-test/dt.sh status # 查看服务状态 ./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 fe-stop pc # 停止 pc 前端
./deploy-test/dt.sh up # pull + build + restart ./deploy-test/dt.sh up # pull + build + restart
./deploy-test/dt.sh deploy # pull + build + restart + status ./deploy-test/dt.sh deploy # pull + build + restart + status
@@ -181,13 +182,18 @@ vim .env.deploy-test
# 7. 安装前端依赖(可选) # 7. 安装前端依赖(可选)
./deploy-test/06-install-frontend.sh ./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 ./deploy-test/07-start-frontend.sh
``` ```
> **pcElectron依赖安装****优先**按上文配置 **GitHub SSH 密钥**;裸机还需 **`00-init-tools.sh`**(见「步骤 0」。若仍无法用 SSH再依赖脚本内的 GitHub **HTTPS 重写**。详见「pc 前端 yarn install 失败」。`pc` 建议仅用 **Yarn**;可删除 `package-lock.json` 消除混用锁文件警告。 > **pcElectron依赖安装****优先**按上文配置 **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弹幕+视频) | | meetingh5 | :5188 | 直播观看 H5弹幕+视频) |
| h5 | :3003 | 移动端 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 访问方式** > **meetingh5 访问方式**
> >
@@ -308,26 +323,56 @@ TENCENT_SDK_SECRET_KEY=xxx
### Nginx 反代(域名 HTTPS 入口,供 PC / 浏览器访问后端) ### 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/im/` | `127.0.0.1:10002` |
| `/api/user/``/api/chat/` | `127.0.0.1:10008` | | `/api/user/``/api/chat/` | `127.0.0.1:10008` |
| `/msg_gateway` | `127.0.0.1:10001`WebSocket | | `/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` 在监听。 1. 服务器上已执行 `05-start.sh` 等,保证 `10001/10002/10008` 在监听。
2. 域名 `pc-jack.imharry.work` 已解析到测试服务器公网 IP。 2. 域名 `pc-jack.imharry.work` 已解析到测试服务器公网 IP。
3. `.env.deploy-test` 中设置 **`PC_BACKEND_ORIGIN=https://pc-jack.imharry.work`**(无末尾 `/`)。 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 4. 仓库根目录执行:`./deploy-test/08-build-static-frontend.sh pc``./deploy-test/dt.sh fe-build-static pc`构建 PC 静态资源
5. 仓库根目录执行:`sudo ./deploy-test/00-init-tools.sh nginx`(会安装 `nginx`,并写入配置 `deploy-test/nginx/openim-pc-proxy.conf`;亦已包含在 `00-init-tools.sh` 无参的 **all** 流程末尾,需 root 5. 如需同时构建 PC / CMS / Build-CMS / Build-Down可直接执行`./deploy-test/08-build-static-frontend.sh`;也可分别构建单个项目
6. 测试服务器本机/安全组放行 **TCP 80**;外层 LB/CDN/网关对公网提供 HTTPS `443` 并转发到本机 `80` 6. 仓库根目录执行:`sudo ./deploy-test/00-init-tools.sh nginx`(会安装 `nginx`,并写入配置 `deploy-test/nginx/openim-pc-proxy.conf`;亦已包含在 `00-init-tools.sh` 无参的 **all** 流程末尾,需 root
7. 浏览器打开 **`https://pc-jack.imharry.work/`** 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 基础设施 ### Docker 基础设施

View File

@@ -231,10 +231,15 @@ normalize_pc_proxy_env() {
PC_PROXY_DOMAIN="${PC_PROXY_DOMAIN:-pc-jack.imharry.work}" PC_PROXY_DOMAIN="${PC_PROXY_DOMAIN:-pc-jack.imharry.work}"
local default_origin="https://${PC_PROXY_DOMAIN}" local default_origin="https://${PC_PROXY_DOMAIN}"
local origin="${PC_BACKEND_ORIGIN:-}" 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%/}" origin="${origin%/}"
if [[ -z "$origin" ]]; then if [[ -z "$origin" ]]; then
PC_BACKEND_ORIGIN="$default_origin" 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 elif [[ -n "${DEPLOY_TEST_IP:-}" ]] && [[ "$origin" =~ ^https?://${DEPLOY_TEST_IP}(:[0-9]+)?$ ]]; then
warn " 检测到旧 PC_BACKEND_ORIGIN=${origin},已切换为 ${default_origin}" warn " 检测到旧 PC_BACKEND_ORIGIN=${origin},已切换为 ${default_origin}"
PC_BACKEND_ORIGIN="$default_origin" PC_BACKEND_ORIGIN="$default_origin"

40
dt.sh
View File

@@ -46,8 +46,11 @@ deploy-test 后端/基础服务:
status 调用 deploy-test/status.sh status 调用 deploy-test/status.sh
deploy-test 前端: deploy-test 前端:
fe-start [project] 调用 deploy-test/07-start-frontend.sh [project] fe-start [project] 调用 deploy-test/07-start-frontend.sh [project](开发态前端)
fe-stop [project] 调用 deploy-test/stop-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 up pull + build + restart
@@ -60,7 +63,9 @@ deploy-test 前端:
./deploy-test/dt.sh pull ./deploy-test/dt.sh pull
./deploy-test/dt.sh build ./deploy-test/dt.sh build
./deploy-test/dt.sh restart ./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 ./deploy-test/dt.sh deploy
EOF EOF
} }
@@ -72,6 +77,14 @@ require_deploy_test() {
fi 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() { run_deploy_test_script() {
local script="$1" local script="$1"
shift || true shift || true
@@ -195,6 +208,27 @@ main() {
fe-stop) fe-stop)
run_deploy_test_script "stop-frontend.sh" "$@" 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) up)
update_all_repos update_all_repos
run_deploy_test_script "04-build.sh" run_deploy_test_script "04-build.sh"

View File

@@ -16,7 +16,8 @@
# #
# 后端服务: openim-server, chat-rpc, admin-rpc, chat-api, admin-api, # 后端服务: openim-server, chat-rpc, admin-rpc, chat-api, admin-api,
# meetingmsg, livecloud, livestream, build-server # 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 # Docker: redis, kafka, etcd, livekit
# ============================================================================= # =============================================================================
set -euo pipefail set -euo pipefail
@@ -63,7 +64,7 @@ if [[ -z "$SVC" ]]; then
echo "" echo ""
echo -e "${BOLD}前端服务日志${NC} ($LOG_DIR/fe-*.log):" 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 for fe in "${FE_LIST[@]}"; do
fe_log="$LOG_DIR/fe-${fe}.log" fe_log="$LOG_DIR/fe-${fe}.log"
if [[ -f "$fe_log" ]]; then if [[ -f "$fe_log" ]]; then
@@ -146,7 +147,7 @@ case "$SVC" in
esac esac
# ── 前端服务日志 ────────────────────────────────────────────────────────────── # ── 前端服务日志 ──────────────────────────────────────────────────────────────
FE_LIST=(pc meetingh5 h5 cms build-cms build-down) FE_LIST=(meetingh5 h5)
for _fe in "${FE_LIST[@]}"; do for _fe in "${FE_LIST[@]}"; do
if [[ "$SVC" == "$_fe" ]]; then if [[ "$SVC" == "$_fe" ]]; then
LOGFILE="$LOG_DIR/fe-${SVC}.log" LOGFILE="$LOG_DIR/fe-${SVC}.log"

View File

@@ -8,7 +8,7 @@
# #
# CORSchat-api:10008与 openim:10001/:10002已在应用内通过 openimsdk/tools/mw.CorsHandler # CORSchat-api:10008与 openim:10001/:10002已在应用内通过 openimsdk/tools/mw.CorsHandler
# 返回 Access-Control-Allow-Origin: *。若在此再用 add_header 追加 $http_origin浏览器会收到 # 返回 Access-Control-Allow-Origin: *。若在此再用 add_header 追加 $http_origin浏览器会收到
# 「*, http://IP:5173」两个值并报错。故本配置不在 Nginx 层添加 CORS预检 OPTIONS 也交给上游处理。 # 「*, http://IP」两个值并报错。故本配置不在 Nginx 层添加 CORS预检 OPTIONS 也交给上游处理。
# #
# 推荐外部访问入口https://pc-jack.imharry.work/ # 推荐外部访问入口https://pc-jack.imharry.work/
# 本 Nginx 仅监听 HTTP :80HTTPS 由外层 LB/CDN/网关终止后转发到本机 :80。 # 本 Nginx 仅监听 HTTP :80HTTPS 由外层 LB/CDN/网关终止后转发到本机 :80。
@@ -110,20 +110,10 @@ server {
return 200 "ok\n"; return 200 "ok\n";
} }
# PC Vite dev:web server. # PC 静态站点dist.
location / { location / {
proxy_pass http://127.0.0.1:5173; root /app/pc/dist;
proxy_http_version 1.1; try_files $uri $uri/ /index.html;
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;
} }
} }
@@ -218,3 +208,27 @@ server {
try_files $uri $uri/ /index.html; 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;
}
}

View File

@@ -297,7 +297,7 @@ await window.__deployTestResetBrowserStorage()
await window.__deployTestManualInitDB() 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/ 并刷新页面 2. 打开 https://pc-jack.imharry.work/ 并刷新页面
3. 重新粘贴本脚本输出的整段 JS刷新会清掉已安装的 probe 3. 重新粘贴本脚本输出的整段 JS刷新会清掉已安装的 probe
4. 再登录 4. 再登录

View File

@@ -80,6 +80,10 @@ echo " ./deploy-test/logs.sh <service> # 实时日志"
echo " ./deploy-test/restart.sh <service> # 重启服务" echo " ./deploy-test/restart.sh <service> # 重启服务"
echo " ./deploy-test/restart.sh <svc> --build # 重编译并重启" echo " ./deploy-test/restart.sh <svc> --build # 重编译并重启"
echo " ./deploy-test/check-conn.sh # 验证 MongoDB / MinIO" 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 ""
echo -e "${BOLD}停止服务:${NC}" echo -e "${BOLD}停止服务:${NC}"
echo " ./deploy-test/stop.sh # 停止后端进程" echo " ./deploy-test/stop.sh # 停止后端进程"

View File

@@ -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 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 Admin API: ${PC_VITE_ADMIN_URL:-${PC_BACKEND_ORIGIN}/api/admin}"
echo " PC WebSocket: ${PC_VITE_WS_URL:-$default_ws_url}" 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" echo " Nginx 日志: /var/log/nginx/openim-pc-proxy-access.log"
pc_probe_msg_gateway "$PC_BACKEND_ORIGIN" pc_probe_msg_gateway "$PC_BACKEND_ORIGIN"
else else
printf " ${YELLOW}${NC} %-14s %s\n" "nginx-health" "跳过(未安装 curl 或未设置 PC_BACKEND_ORIGIN" printf " ${YELLOW}${NC} %-14s %s\n" "nginx-health" "跳过(未安装 curl 或未设置 PC_BACKEND_ORIGIN"
fi 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 "<html"; then
title="$(printf '%s' "$body" | grep -oiE '<title>[^<]*</title>' | head -1 | sed -E 's#</?title>##g' || true)"
if [[ -n "$title" ]]; then
printf " ${CYAN}${NC} %-14s %s\n" "${label}-title" "$title"
else
printf " ${CYAN}${NC} %-14s %s\n" "${label}-title" "(未解析到 <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 ""
echo -e "${BOLD}[ 前端开发服务器 ]${NC}" echo -e "${BOLD}[ 前端开发服务器 ]${NC}"
fe_port_desc() { fe_port_desc() {
case "$1" in case "$1" in
pc) echo "5173 (yarn dev:web)" ;;
meetingh5) echo "5188" ;; meetingh5) echo "5188" ;;
h5) echo "3003" ;; h5) echo "3003" ;;
cms) echo "8001" ;;
build-cms) echo "8002" ;;
build-down) echo "8003" ;;
*) echo "?" ;; *) echo "?" ;;
esac 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" pidfile="$PID_DIR/fe-${fe}.pid"
logfile="$LOG_DIR/fe-${fe}.log" logfile="$LOG_DIR/fe-${fe}.log"
port_desc="$(fe_port_desc "$fe")" port_desc="$(fe_port_desc "$fe")"
@@ -183,7 +217,7 @@ done
# ── 端口占用检查 ────────────────────────────────────────────────────────────── # ── 端口占用检查 ──────────────────────────────────────────────────────────────
echo "" echo ""
echo -e "${BOLD}[ 端口占用 ]${NC}" 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 for port in "${PORTS[@]}"; do
pid=$(lsof -ti :"$port" 2>/dev/null | head -1 || true) pid=$(lsof -ti :"$port" 2>/dev/null | head -1 || true)
if [[ -n "$pid" ]]; then if [[ -n "$pid" ]]; then
@@ -197,10 +231,12 @@ done
# ── 快速操作提示 ────────────────────────────────────────────────────────────── # ── 快速操作提示 ──────────────────────────────────────────────────────────────
echo "" echo ""
echo -e "${BOLD}[ 快捷命令 ]${NC}" 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 <service> 重启后端服务"
echo " ./deploy-test/restart.sh <svc> --build 重编译并重启" 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/stop-frontend.sh 停止前端服务"
echo " ./deploy-test/check-conn.sh 验证 MongoDB/S3 连接" echo " ./deploy-test/check-conn.sh 验证 MongoDB/S3 连接"
echo "" echo ""

View File

@@ -6,23 +6,21 @@
# ./stop-frontend.sh # 停止全部前端服务 # ./stop-frontend.sh # 停止全部前端服务
# ./stop-frontend.sh <project> # 只停止指定项目 # ./stop-frontend.sh <project> # 只停止指定项目
# #
# 可用项目: pc, meetingh5, h5, cms, build-cms, build-down # 可用项目: meetingh5, h5
# 注意: pc / cms / build-cms / build-down 已改为静态构建,不再通过本脚本管理
# ============================================================================= # =============================================================================
set -euo pipefail set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
init_dirs init_dirs
init_script_log # ← 脚本执行日志 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}" TARGET="${1:-all}"
declare -A FE_PORT_NUM=( declare -A FE_PORT_NUM=(
[pc]="5173"
[meetingh5]="5188" [meetingh5]="5188"
[h5]="3003" [h5]="3003"
[cms]="8001"
[build-cms]="8002"
[build-down]="8003"
) )
_stop_fe() { _stop_fe() {
@@ -98,13 +96,20 @@ if [[ "$TARGET" == "all" ]]; then
done done
success "所有前端服务已停止" success "所有前端服务已停止"
else 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 local_valid=false
for p in "${FE_PROJECTS[@]}"; do for p in "${FE_PROJECTS[@]}"; do
[[ "$p" == "$TARGET" ]] && local_valid=true && break [[ "$p" == "$TARGET" ]] && local_valid=true && break
done done
if ! $local_valid; then if ! $local_valid; then
error "未知项目: $TARGET" error "未知项目: $TARGET"
echo "可用: ${FE_PROJECTS[*]}" echo "开发态前端可用: ${FE_PROJECTS[*]}"
exit 1 exit 1
fi fi
step "停止: $TARGET" step "停止: $TARGET"