166 lines
5.4 KiB
Bash
Executable File
166 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Plaza 独立部署 → 105(与 Memind H5 解耦,仅共享同机 API)
|
||
#
|
||
# 架构:
|
||
# plaza.tkmind.cn
|
||
# /plaza、/_next → goose-plaza-web :3002 (/root/plaza/web)
|
||
# /api、/auth、/u → goose-h5 :8080 (/root/tkmind_go/ui/h5)
|
||
#
|
||
# 用法:
|
||
# pnpm deploy:plaza-105
|
||
# pnpm deploy:plaza-105 -- --skip-build
|
||
# pnpm deploy:plaza-105 -- --no-restart
|
||
#
|
||
# 前置:
|
||
# 1. DNS: plaza.tkmind.cn A → 120.26.184.105(公网入口);运维/部署直接使用固定公网 IP
|
||
# 2. H5 已部署:pnpm deploy:105(提供 Plaza API + 登录 + 发布页)
|
||
# 3. 可选:cp deploy/plaza-105/plaza-105.env.example deploy/plaza-105/plaza-105.env
|
||
set -euo pipefail
|
||
|
||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||
DEPLOY_DIR="${ROOT}/deploy/plaza-105"
|
||
DEPLOY_ENV="${DEPLOY_DIR}/plaza-105.env"
|
||
EXCLUDE="${ROOT}/scripts/.rsync-exclude-plaza-web"
|
||
|
||
PLAZA_APP_DIR="${PLAZA_APP_DIR:-${ROOT}/../memind_plaza}"
|
||
PLAZA_DEPLOY_HOST="${PLAZA_DEPLOY_HOST:-root@120.26.184.105}"
|
||
PLAZA_REMOTE_DIR="${PLAZA_REMOTE_DIR:-/root/plaza/web}"
|
||
PLAZA_PROD_URL="${PLAZA_PROD_URL:-https://plaza.tkmind.cn}"
|
||
PLAZA_PORT="${PLAZA_PORT:-3002}"
|
||
PLAZA_SYSTEMD_SERVICE="${PLAZA_SYSTEMD_SERVICE:-goose-plaza-web}"
|
||
H5_SYSTEMD_SERVICE="${H5_SYSTEMD_SERVICE:-goose-h5}"
|
||
MINDSPACE_PUBLIC_BASE="${MINDSPACE_PUBLIC_BASE:-https://m.tkmind.cn}"
|
||
|
||
SKIP_BUILD=0
|
||
NO_RESTART=0
|
||
|
||
for arg in "$@"; do
|
||
case "$arg" in
|
||
--skip-build) SKIP_BUILD=1 ;;
|
||
--no-restart) NO_RESTART=1 ;;
|
||
-h|--help)
|
||
sed -n '2,18p' "$0"
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo "未知参数: $arg(可用 --skip-build / --no-restart)" >&2
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
if [[ -f "${DEPLOY_ENV}" ]]; then
|
||
set -a
|
||
# shellcheck disable=SC1090
|
||
source "${DEPLOY_ENV}"
|
||
set +a
|
||
fi
|
||
|
||
if [[ ! -f "${PLAZA_APP_DIR}/package.json" ]]; then
|
||
echo "错误: 未找到 Plaza Next.js:${PLAZA_APP_DIR}" >&2
|
||
echo "请设置 PLAZA_APP_DIR 或确认 tkmind_go/ui/plaza 存在" >&2
|
||
exit 1
|
||
fi
|
||
|
||
ssh_cmd() {
|
||
ssh -o ConnectTimeout=15 -o BatchMode=yes "${PLAZA_DEPLOY_HOST}" "$@"
|
||
}
|
||
|
||
write_remote_env() {
|
||
ssh_cmd "mkdir -p '${PLAZA_REMOTE_DIR}' && cat > '${PLAZA_REMOTE_DIR}/.env' <<EOF
|
||
PLAZA_API_PROXY=http://127.0.0.1:8080
|
||
PLAZA_API_BASE=http://127.0.0.1:8080
|
||
NEXT_PUBLIC_API_BASE=${PLAZA_PROD_URL}
|
||
NEXT_PUBLIC_SITE_BASE=${PLAZA_PROD_URL}
|
||
NEXT_PUBLIC_MINDSPACE_BASE=${MINDSPACE_PUBLIC_BASE}
|
||
NEXT_PUBLIC_PLAZA_BASE=/plaza
|
||
EOF"
|
||
}
|
||
|
||
install_nginx() {
|
||
echo "==> 安装 Nginx 配置..."
|
||
ssh_cmd "mkdir -p /var/www/certbot"
|
||
|
||
if ssh_cmd "test -f /etc/letsencrypt/live/plaza.tkmind.cn/fullchain.pem"; then
|
||
scp "${DEPLOY_DIR}/plaza.tkmind.cn.nginx.conf" \
|
||
"${PLAZA_DEPLOY_HOST}:/etc/nginx/conf.d/plaza.tkmind.cn.conf"
|
||
ssh_cmd "nginx -t && systemctl reload nginx"
|
||
return
|
||
fi
|
||
|
||
echo "==> 首次部署:启用 HTTP bootstrap..."
|
||
scp "${DEPLOY_DIR}/plaza.tkmind.cn.bootstrap.nginx.conf" \
|
||
"${PLAZA_DEPLOY_HOST}:/etc/nginx/conf.d/plaza.tkmind.cn.conf"
|
||
ssh_cmd "nginx -t && systemctl reload nginx"
|
||
|
||
echo "==> 申请 SSL 证书..."
|
||
ssh_cmd "certbot certonly --webroot -w /var/www/certbot -d plaza.tkmind.cn \
|
||
--non-interactive --agree-tos -m admin@tkmind.cn || true"
|
||
|
||
if ssh_cmd "test -f /etc/letsencrypt/live/plaza.tkmind.cn/fullchain.pem"; then
|
||
scp "${DEPLOY_DIR}/plaza.tkmind.cn.nginx.conf" \
|
||
"${PLAZA_DEPLOY_HOST}:/etc/nginx/conf.d/plaza.tkmind.cn.conf"
|
||
else
|
||
echo "⚠ 证书未签发,暂保留 HTTP bootstrap"
|
||
fi
|
||
|
||
ssh_cmd "nginx -t && systemctl reload nginx"
|
||
}
|
||
|
||
install_systemd() {
|
||
echo "==> 安装 systemd (${PLAZA_SYSTEMD_SERVICE})..."
|
||
scp "${DEPLOY_DIR}/goose-plaza-web.service" \
|
||
"${PLAZA_DEPLOY_HOST}:/etc/systemd/system/${PLAZA_SYSTEMD_SERVICE}.service"
|
||
ssh_cmd "systemctl daemon-reload && systemctl enable '${PLAZA_SYSTEMD_SERVICE}'"
|
||
}
|
||
|
||
echo "======================================"
|
||
echo "Plaza 独立部署 → 105"
|
||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||
echo "前端: ${PLAZA_APP_DIR}"
|
||
echo "远端: ${PLAZA_DEPLOY_HOST}:${PLAZA_REMOTE_DIR}"
|
||
echo "公网: ${PLAZA_PROD_URL}"
|
||
echo "API: goose-h5 @ :8080(需已 deploy:105)"
|
||
echo "======================================"
|
||
|
||
echo "==> rsync Plaza Next.js..."
|
||
rsync -az --delete --exclude-from="${EXCLUDE}" \
|
||
"${PLAZA_APP_DIR}/" \
|
||
"${PLAZA_DEPLOY_HOST}:${PLAZA_REMOTE_DIR}/"
|
||
|
||
write_remote_env
|
||
|
||
if [[ "${SKIP_BUILD}" -eq 0 ]]; then
|
||
echo "==> 远端 npm install && build..."
|
||
ssh_cmd "cd '${PLAZA_REMOTE_DIR}' && npm install && npm run build"
|
||
fi
|
||
|
||
install_systemd
|
||
install_nginx
|
||
|
||
if [[ "${NO_RESTART}" -eq 0 ]]; then
|
||
echo "==> 重启服务..."
|
||
ssh_cmd "systemctl is-active --quiet '${H5_SYSTEMD_SERVICE}' || {
|
||
echo '⚠ ${H5_SYSTEMD_SERVICE} 未运行,Plaza API 不可用。请先 pnpm deploy:105' >&2
|
||
exit 1
|
||
}"
|
||
ssh_cmd "systemctl restart '${PLAZA_SYSTEMD_SERVICE}'"
|
||
sleep 2
|
||
fi
|
||
|
||
echo ""
|
||
echo "=== 健康检查 ==="
|
||
ssh_cmd "systemctl is-active '${PLAZA_SYSTEMD_SERVICE}' && echo '${PLAZA_SYSTEMD_SERVICE}: active'"
|
||
ssh_cmd "curl -sf 'http://127.0.0.1:8080/api/status' && echo ' ← plaza-api (goose-h5) ok'" || {
|
||
echo "✗ goose-h5 API 不可用,请执行 pnpm deploy:105" >&2
|
||
exit 1
|
||
}
|
||
ssh_cmd "curl -s -o /dev/null -w 'plaza-web local → %{http_code}\n' 'http://127.0.0.1:${PLAZA_PORT}/plaza'" || true
|
||
curl -s --max-time 20 -o /dev/null -w "${PLAZA_PROD_URL}/plaza → %{http_code}\n" "${PLAZA_PROD_URL}/plaza" || true
|
||
|
||
echo ""
|
||
echo "✅ Plaza 前端已独立部署"
|
||
echo " 首页: ${PLAZA_PROD_URL}/plaza"
|
||
echo " 目录: ${PLAZA_REMOTE_DIR}"
|
||
echo " API: 仍由 goose-h5 提供(pnpm deploy:105 同步)"
|