Add LAN deploy scripts and improve admin billing/users UX.
Provide rsync deploy and restart tooling for the 100 server, document the workflow, and add pagination plus user filtering across billing and user management pages. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
.git
|
||||
.gitignore
|
||||
.DS_Store
|
||||
node_modules
|
||||
.env
|
||||
.env.local
|
||||
*.local
|
||||
.vite
|
||||
*.log
|
||||
logs
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/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_PATH="${LAN_NODE_PATH:-/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin}"
|
||||
LOG="${ROOT}/adm-preview.log"
|
||||
PID_FILE="${ROOT}/.adm-preview.pid"
|
||||
|
||||
export PATH="${NODE_PATH}:${PATH}"
|
||||
command -v node >/dev/null 2>&1 || { echo "❌ 未找到 node" >&2; exit 1; }
|
||||
|
||||
cd "${ROOT}"
|
||||
|
||||
if [[ ! -d dist ]]; then
|
||||
echo "❌ ${ROOT}/dist 不存在,请先构建或 rsync dist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d node_modules ]]; then
|
||||
echo "==> 安装依赖..."
|
||||
npm install
|
||||
fi
|
||||
|
||||
echo "==> 停止旧进程 (port ${PORT})..."
|
||||
lsof -ti "TCP:${PORT}" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true
|
||||
sleep 1
|
||||
lsof -ti "TCP:${PORT}" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true
|
||||
|
||||
echo "==> 启动 vite preview @ 127.0.0.1:${PORT}..."
|
||||
nohup npm run preview -- --host 127.0.0.1 --port "${PORT}" >>"${LOG}" 2>&1 &
|
||||
echo $! >"${PID_FILE}"
|
||||
sleep 2
|
||||
|
||||
if curl -sf "http://127.0.0.1:${PORT}/" >/dev/null; then
|
||||
echo "✅ memind_adm 已就绪: http://127.0.0.1:${PORT}/"
|
||||
curl -sf "http://127.0.0.1:${PORT}/" >/dev/null && echo " 首页 OK"
|
||||
else
|
||||
echo "❌ 启动失败,最近日志:" >&2
|
||||
tail -n 40 "${LOG}" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bash
|
||||
# memind_adm → 100 服务器 rsync 部署
|
||||
#
|
||||
# 用法:
|
||||
# ./scripts/rsync_to_server.sh
|
||||
# ./scripts/rsync_to_server.sh --skip-build
|
||||
# ./scripts/rsync_to_server.sh --no-restart
|
||||
# SKIP_BUILD=1 NO_RESTART=1 ./scripts/rsync_to_server.sh
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
EXCLUDE="${ROOT}/scripts/.rsync-exclude-lan"
|
||||
DEPLOY_HOST="${DEPLOY_HOST:-john@100.99.38.66}"
|
||||
REMOTE_DIR="${REMOTE_DIR:-/Users/john/Project/memind_adm}"
|
||||
ADM_PORT="${ADM_PORT:-5174}"
|
||||
SSH_OPTS=(-o ConnectTimeout=15 -o BatchMode=yes -o StrictHostKeyChecking=accept-new)
|
||||
|
||||
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,8p' "$0"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知参数: $arg" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
ssh_cmd() {
|
||||
ssh "${SSH_OPTS[@]}" "${DEPLOY_HOST}" "$@"
|
||||
}
|
||||
|
||||
require_ssh() {
|
||||
if ! ssh_cmd 'echo ok' >/dev/null 2>&1; then
|
||||
echo "❌ 无法 SSH 到 ${DEPLOY_HOST}" >&2
|
||||
echo "请确认 Tailscale 已连接,或执行: ssh-copy-id ${DEPLOY_HOST}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo "======================================"
|
||||
echo "memind_adm → ${DEPLOY_HOST}"
|
||||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "本地: ${ROOT}"
|
||||
echo "远端: ${REMOTE_DIR}"
|
||||
echo "端口: ${ADM_PORT}"
|
||||
echo "======================================"
|
||||
|
||||
require_ssh
|
||||
|
||||
if [[ "${SKIP_BUILD}" -eq 0 ]]; then
|
||||
echo "==> 本地构建..."
|
||||
cd "${ROOT}"
|
||||
npm run build
|
||||
fi
|
||||
|
||||
echo "==> 创建远端目录..."
|
||||
ssh_cmd "mkdir -p '${REMOTE_DIR}'"
|
||||
|
||||
echo "==> rsync 源码 (--delete)..."
|
||||
rsync -az --delete --exclude-from="${EXCLUDE}" \
|
||||
"${ROOT}/" \
|
||||
"${DEPLOY_HOST}:${REMOTE_DIR}/"
|
||||
|
||||
echo "==> rsync dist..."
|
||||
rsync -az --delete \
|
||||
"${ROOT}/dist/" \
|
||||
"${DEPLOY_HOST}:${REMOTE_DIR}/dist/"
|
||||
|
||||
echo "==> 写入远端 .env(不覆盖已有)..."
|
||||
ssh_cmd "test -f '${REMOTE_DIR}/.env' || cat > '${REMOTE_DIR}/.env' <<'EOF'
|
||||
ADM_DEV_BACKEND=http://127.0.0.1:8081
|
||||
VITE_MAIN_APP_URL=http://127.0.0.1:8081
|
||||
EOF"
|
||||
|
||||
if [[ "${NO_RESTART}" -eq 0 ]]; then
|
||||
echo "==> 远端重启服务..."
|
||||
ssh_cmd "ADM_ROOT='${REMOTE_DIR}' ADM_PORT='${ADM_PORT}' bash -s" <"${ROOT}/scripts/remote_restart.sh"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ 已部署到 ${DEPLOY_HOST}:${REMOTE_DIR}"
|
||||
echo " 本机访问: ssh ${DEPLOY_HOST} 'curl -sI http://127.0.0.1:${ADM_PORT}/ | head -1'"
|
||||
Reference in New Issue
Block a user