fix: 修复会话鉴权「登录后 token 无效」并补齐 NAS 部署流程
- deps.py: _create_redis_client 增加同步 ping 校验,Redis 不可达时正确降级为内存模式 - main.py: lifespan 复用 deps 的 UserStore 单例,避免 admin 与 API 请求实例不一致 - 前端: 强制改密弹窗(must_change_password 用户)、兼容新旧登录返回格式、markPasswordChanged - 新增 NAS SSH 部署脚本与批处理测试;gitignore 前端构建产物
This commit is contained in:
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# QMDSearch NAS 端自动部署钩子 (post-receive)
|
||||
#
|
||||
# 这是真正的「持续部署(CD)」:当本地 deploy.sh 把代码 push 到 NAS 后,
|
||||
# 此钩子自动完成 checkout → 按需构建 → 重启/重建容器 → 健康检查 → 失败回滚。
|
||||
#
|
||||
# 安装方式(二选一):
|
||||
# A. 作为 bare 仓库的 hook(推荐,全自动):
|
||||
# # 假设 NAS 上 bare 仓库在 /volume1/git/QMDSearch.git,工作树在 /volume1/docker/QMDSearch
|
||||
# cp scripts/nas-post-receive /volume1/git/QMDSearch.git/hooks/post-receive
|
||||
# chmod +x /volume1/git/QMDSearch.git/hooks/post-receive
|
||||
# # 在该 bare 仓库 config 中设置:
|
||||
# # [core] bare = true
|
||||
# # [hooks] 并确保工作树目录已 clone 过一次
|
||||
# # 首次需手动:git --work-tree=/volume1/docker/QMDSearch --git-dir=/volume1/git/QMDSearch.git checkout -f
|
||||
#
|
||||
# B. 作为普通脚本手动触发(无 bare 仓库时):
|
||||
# cd /volume1/docker/QMDSearch && git pull && sudo bash scripts/nas-post-receive
|
||||
#
|
||||
# 前置依赖(NAS 上需具备):git、docker、docker compose、node/npm
|
||||
# 可调环境变量:DEPLOY_DIR(工作树)、APP_PORT、LOG_FILE
|
||||
# =============================================================================
|
||||
set -uo pipefail
|
||||
|
||||
DEPLOY_DIR="${DEPLOY_DIR:-/volume1/docker/QMDSearch}" # ← 改成你的 NAS 部署目录
|
||||
GIT_DIR="$DEPLOY_DIR/.git"
|
||||
LOG_FILE="${LOG_FILE:-$DEPLOY_DIR/deploy.log}"
|
||||
APP_PORT="${APP_PORT:-8000}"
|
||||
PREV_COMMIT_FILE="$DEPLOY_DIR/.last_deployed_commit"
|
||||
|
||||
log(){ printf '%s [nas-deploy] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" | tee -a "$LOG_FILE"; }
|
||||
|
||||
rollback(){
|
||||
log "回滚到上一稳定提交: ${PREV:-<无>}"
|
||||
if [[ -n "${PREV:-}" ]]; then
|
||||
git --work-tree="$DEPLOY_DIR" --git-dir="$GIT_DIR" checkout -f "$PREV"
|
||||
(cd "$DEPLOY_DIR" && docker compose restart app) | tee -a "$LOG_FILE"
|
||||
echo "$PREV" > "$PREV_COMMIT_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# 解析 post-receive 通过 stdin 传入的 <old> <new> <ref>
|
||||
newrev=""; refname=""
|
||||
while read -r oldrev newrev refname; do :; done
|
||||
# 仅处理 main 分支的推送;手动运行时 newrev 为空,回退到 HEAD
|
||||
if [[ -z "$newrev" ]]; then
|
||||
newrev="$(git --git-dir="$GIT_DIR" rev-parse HEAD 2>/dev/null || echo "")"
|
||||
fi
|
||||
if [[ -n "$refname" && "$refname" != "refs/heads/main" ]]; then
|
||||
log "忽略非 main 分支推送 ($refname)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "=== 开始部署 (newrev=${newrev:0:8}) ==="
|
||||
|
||||
# 1) 检出到工作树
|
||||
git --work-tree="$DEPLOY_DIR" --git-dir="$GIT_DIR" checkout -f
|
||||
cd "$DEPLOY_DIR" || { log "无法进入 $DEPLOY_DIR"; exit 1; }
|
||||
|
||||
# 2) 计算变化范围
|
||||
PREV="$(cat "$PREV_COMMIT_FILE" 2>/dev/null || echo "")"
|
||||
if [[ -n "$PREV" && -n "$newrev" ]]; then
|
||||
CHANGED="$(git --git-dir="$GIT_DIR" diff --name-only "$PREV" "$newrev")"
|
||||
else
|
||||
CHANGED="$(git --git-dir="$GIT_DIR" show --name-only --format= "$newrev")"
|
||||
fi
|
||||
|
||||
has(){ echo "$CHANGED" | grep -qE "$1"; }
|
||||
FE_CHANGED=0; DEPS_CHANGED=0
|
||||
has '^frontend/(src/|public/|index\.html|package\.json|vite\.config|package-lock\.json)' && FE_CHANGED=1
|
||||
has '^(pyproject\.toml|uv\.lock|Dockerfile)' && DEPS_CHANGED=1
|
||||
log "变更范围 → frontend=$FE_CHANGED deps=$DEPS_CHANGED"
|
||||
|
||||
# 3) 按需构建前端(dist 不入库,必须在此构建)
|
||||
if [[ "$FE_CHANGED" -eq 1 ]]; then
|
||||
log "检测前端变化,重新构建..."
|
||||
if ! (cd frontend && npm ci --no-audit --no-fund && npm run build) 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "前端构建失败,中止部署(保留上一版本)"; exit 1
|
||||
fi
|
||||
ok(){ :; }; log "前端构建完成"
|
||||
fi
|
||||
|
||||
# 4) 部署容器
|
||||
if [[ "$DEPS_CHANGED" -eq 1 ]]; then
|
||||
log "依赖变化,重建镜像并重启: docker compose up -d --build app"
|
||||
docker compose up -d --build app 2>&1 | tee -a "$LOG_FILE"
|
||||
else
|
||||
log "仅代码变化,重启 app 服务: docker compose restart app"
|
||||
docker compose restart app 2>&1 | tee -a "$LOG_FILE"
|
||||
fi
|
||||
|
||||
# 5) 健康检查(失败自动回滚)
|
||||
log "健康检查 http://localhost:$APP_PORT/health ..."
|
||||
for i in $(seq 1 15); do
|
||||
if curl -fsS "http://localhost:$APP_PORT/health" >/dev/null 2>&1; then
|
||||
log "健康检查通过 ✓"
|
||||
[[ -n "$newrev" ]] && echo "$newrev" > "$PREV_COMMIT_FILE"
|
||||
log "=== 部署完成 ==="
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
log "健康检查失败,触发回滚"
|
||||
rollback
|
||||
exit 1
|
||||
Reference in New Issue
Block a user