新增本机部署脚本 deploy/deploy.sh(build/start/stop/restart/status/log+健康检查), 凭据走 gitignore 的 deploy/.env.dev; README 补部署说明

This commit is contained in:
xiaoqu
2026-09-03 15:05:02 +08:00
parent b44fa9a86a
commit 7eaf51973a
4 changed files with 125 additions and 0 deletions
+5
View File
@@ -4,3 +4,8 @@ target/
*.iml
.vscode/
.DS_Store
# 本地部署凭据与运行态
deploy/.env.dev
deploy/app.pid
logs/
+12
View File
@@ -111,6 +111,18 @@ nohup java -jar target/xiaoqu-agent-service.jar > target/app.log 2>&1 &
- 不提供默认 profile、数据库账号或密码;缺失配置时不得启动。
- dev 端口 **8088**,MCP 端点 `http://localhost:8088/mcp`。
### 部署脚本(推荐,本机 dev 部署)
```bash
cp deploy/.env.example deploy/.env.dev # 填写 dev 凭据(已 gitignore,不入库)
./deploy/deploy.sh build # 构建 jar
./deploy/deploy.sh restart # 停旧起新 + 健康检查(/mcp 返回 401/200 即就绪)
./deploy/deploy.sh status | log | stop # 状态 / 跟踪日志 / 停止
```
- 凭据从 `deploy/.env.dev` 读取,无需手工 export;日志在 `logs/agent-service.log`,pid 在 `deploy/app.pid`。
- 注意应用启动较慢(多数据源初始化,约 60-90s),脚本健康检查窗口已放宽到 180s。
## 测试 ak(仅 dev)
仓库不提供固定 ak。每位开发者在本地生成随机 ak,只把 SHA-256 写入 `agent_api_key`,再用 `token_scope` 关联需要的作用域;明文只保存在本地环境变量中,不提交版本库。仓库历史中曾出现的 dev ak 必须视为已泄露并在数据库中禁用。
+11
View File
@@ -0,0 +1,11 @@
# dev 环境凭据(本文件为模板;实际使用复制为 .env.dev,已 gitignore)
# 取值参考 xiaoqu-franchisee/pom.xml dev profile
M0_DB_USERNAME=root
M0_DB_PASSWORD=
M1_DB_USERNAME=root
M1_DB_PASSWORD=
M2_DB_USERNAME=root
M2_DB_PASSWORD=
SVC_DB_USERNAME=root
SVC_DB_PASSWORD=
REDIS_PASSWORD=
+97
View File
@@ -0,0 +1,97 @@
#!/usr/bin/env bash
# xiaoqu-agent-service 本机部署脚本(dev:本机开发 + 本机运行)
# 用法: ./deploy/deploy.sh {build|start|stop|restart|status|log}
# 凭据: 首次使用复制 deploy/.env.example 为 deploy/.env.dev 并填写(该文件已 gitignore,不入库)
set -euo pipefail
APP_HOME="$(cd "$(dirname "$0")/.." && pwd)"
JAR="$APP_HOME/target/xiaoqu-agent-service.jar"
ENV_FILE="$APP_HOME/deploy/.env.dev"
PID_FILE="$APP_HOME/deploy/app.pid"
LOG_DIR="$APP_HOME/logs"
LOG_FILE="$LOG_DIR/agent-service.log"
PORT=8088
PROFILE=dev
load_env() {
if [ ! -f "$ENV_FILE" ]; then
echo "[ERROR] 缺少 $ENV_FILE,请复制 deploy/.env.example 并填写 dev 凭据" >&2
exit 1
fi
set -a; source "$ENV_FILE"; set +a
}
is_running() {
[ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null
}
health_check() {
# /mcp 未带 ak 会返回 401,带 ak 返回 200——两者都证明服务已起来
for i in $(seq 1 90); do
code=$(curl -s -o /dev/null -w "%{http_code}" -X POST "http://127.0.0.1:$PORT/mcp" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"deploy-check","version":"0"}}}' || true)
if [ "$code" = "200" ] || [ "$code" = "401" ]; then
echo "[OK] 服务已就绪 (HTTP $code, /mcp)"
return 0
fi
sleep 2
done
echo "[ERROR] 健康检查超时,查看日志: tail -f $LOG_FILE" >&2
return 1
}
do_build() {
cd "$APP_HOME"
./mvnw clean package -DskipTests
echo "[OK] 构建完成: $JAR"
}
do_start() {
if is_running; then
echo "[SKIP] 已在运行 (pid $(cat "$PID_FILE"))"
return 0
fi
[ -f "$JAR" ] || { echo "[ERROR] 未找到 jar,先执行: $0 build" >&2; exit 1; }
load_env
mkdir -p "$LOG_DIR"
cd "$APP_HOME"
nohup java -jar "$JAR" --spring.profiles.active="$PROFILE" >> "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "[OK] 已启动 (pid $(cat "$PID_FILE")),等待健康检查..."
health_check
}
do_stop() {
if is_running; then
kill "$(cat "$PID_FILE")"
for i in $(seq 1 15); do is_running || break; sleep 1; done
is_running && { echo "[WARN] 优雅退出超时,强制 kill -9"; kill -9 "$(cat "$PID_FILE")"; }
echo "[OK] 已停止"
else
echo "[SKIP] 未在运行"
fi
rm -f "$PID_FILE"
}
do_status() {
if is_running; then
echo "运行中 (pid $(cat "$PID_FILE"), port $PORT)"
else
echo "未运行"
exit 1
fi
}
case "${1:-}" in
build) do_build ;;
start) do_start ;;
stop) do_stop ;;
restart) do_stop; do_start ;;
status) do_status ;;
log) tail -f "$LOG_FILE" ;;
*)
echo "用法: $0 {build|start|stop|restart|status|log}" >&2
exit 1 ;;
esac