#!/usr/bin/env bash # 在 100 服务器上重启 memind_adm(vite preview + API 反代) set -euo pipefail ROOT="${ADM_ROOT:-/Users/john/Project/memind_adm}" PORT="${ADM_PORT:-5174}" NODE_BIN="${NODE_BIN:-/opt/homebrew/opt/node@24/bin/node}" API_PORT="${ADM_API_PORT:-8085}" LOG="${ROOT}/adm-preview.log" API_LOG="${ROOT}/adm-api.log" PID_FILE="${ROOT}/.adm-preview.pid" API_PID_FILE="${ROOT}/.adm-api.pid" [[ -x "${NODE_BIN}" ]] || { echo "❌ NODE_BIN 不可执行: ${NODE_BIN}" >&2; exit 1; } NODE_DIR="$(dirname "${NODE_BIN}")" export PATH="${NODE_DIR}:${PATH}" NPM_BIN="${NPM_BIN:-${NODE_DIR}/npm}" [[ -x "${NPM_BIN}" ]] || { echo "❌ NPM_BIN 不可执行: ${NPM_BIN}" >&2; exit 1; } cd "${ROOT}" if [[ -f "${ROOT}/.env" ]]; then set -a # shellcheck disable=SC1091 source "${ROOT}/.env" set +a fi BASE_PATH="${VITE_BASE_PATH:-/ops}" if [[ "${BASE_PATH}" != */ ]]; then BASE_PATH="${BASE_PATH}/" fi API_HOST="${ADM_API_HOST:-127.0.0.1}" WEB_HOST="${ADM_WEB_HOST:-${API_HOST}}" export ADM_API_HOST="${API_HOST}" export ADM_WEB_HOST="${WEB_HOST}" export ADM_PORT="${PORT}" export VITE_BASE_PATH="${BASE_PATH%/}" if [[ ! -d dist ]]; then echo "❌ ${ROOT}/dist 不存在,请先构建或 rsync dist" >&2 exit 1 fi if [[ ! -d node_modules ]]; then echo "==> 安装依赖..." "${NPM_BIN}" install fi echo "==> 停止旧进程 (port ${PORT}, ${API_PORT})..." if [[ -f "${PID_FILE}" ]]; then kill "$(cat "${PID_FILE}")" 2>/dev/null || true fi if [[ -f "${API_PID_FILE}" ]]; then kill "$(cat "${API_PID_FILE}")" 2>/dev/null || true fi lsof -ti "TCP:${PORT}" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true lsof -ti "TCP:${API_PORT}" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true sleep 2 lsof -ti "TCP:${PORT}" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true lsof -ti "TCP:${API_PORT}" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true sleep 1 echo "==> 启动 Admin API @ ${API_HOST}:${API_PORT}..." nohup "${NODE_BIN}" server/index.mjs >>"${API_LOG}" 2>&1 & echo $! >"${API_PID_FILE}" sleep 2 if ! curl -sf "http://127.0.0.1:${API_PORT}/health" >/dev/null; then echo "❌ Admin API 启动失败,最近日志:" >&2 tail -n 40 "${API_LOG}" >&2 || true exit 1 fi echo "==> 启动 vite preview @ ${WEB_HOST}:${PORT} (base=${BASE_PATH})..." VITE_BIN="${ROOT}/node_modules/vite/bin/vite.js" [[ -f "${VITE_BIN}" ]] || { echo "❌ 缺少 ${VITE_BIN}" >&2; exit 1; } nohup "${NODE_BIN}" "${VITE_BIN}" preview --config scripts/vite-preview.config.mjs >>"${LOG}" 2>&1 & echo $! >"${PID_FILE}" sleep 3 preview_url="http://127.0.0.1:${PORT}${BASE_PATH}" login_probe="http://127.0.0.1:${PORT}/auth/status" auth_ok=0 for _ in 1 2 3 4 5; do if curl -sf "${preview_url}" >/dev/null && curl -sf "${login_probe}" >/dev/null; then auth_ok=1 break fi sleep 2 done if [[ "${auth_ok}" -eq 1 ]]; then echo "✅ memind_adm 已就绪: ${preview_url}" curl -sf "${preview_url}" >/dev/null && echo " 首页 OK" echo " /auth 反代 OK" echo " 登录请使用数据库中已初始化的 admin 账号" else echo "❌ 启动失败,最近日志:" >&2 tail -n 40 "${LOG}" >&2 || true exit 1 fi