From e4a8cc68b473ac070f24da925c605fe5a71ab5f7 Mon Sep 17 00:00:00 2001 From: gouki Date: Sun, 9 Aug 2026 20:27:02 +0000 Subject: [PATCH] =?UTF-8?q?feat(deploy):=20=E9=9B=B6SSH=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96=E9=83=A8=E7=BD=B2=E2=80=94=E2=80=94update.sh=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=90=8C=E6=AD=A5systemd=E5=8D=95=E5=85=83/=E6=9B=B4?= =?UTF-8?q?=E6=96=B0timer=E7=BC=A9=E8=87=B31=E5=88=86=E9=92=9F/=E6=96=B0?= =?UTF-8?q?=E5=A2=9Edeploy.sh=E4=B8=80=E9=94=AE=E9=83=A8=E7=BD=B2=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/deploy.sh | 77 +++++++++++++++++++++++++++++++++ deploy/update.sh | 28 +++++++++++- deploy/vps-manager-update.timer | 4 +- 3 files changed, 106 insertions(+), 3 deletions(-) create mode 100755 deploy/deploy.sh diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100755 index 0000000..604b857 --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# vps-manager 本地一键部署(零 SSH) +# +# 流程: +# 1. 检查工作区干净 → git push 到 Gitea +# 2. 轮询 cc1 的 /health(含 commit 字段)直到线上版本追平本地 HEAD +# (cc1 上 vps-manager-update.timer 每 1 分钟自动拉取并重启) +# 3. 验证核心 API 全部 200 +# +# 可配置项(环境变量): +# DEPLOY_HEALTH_URL 健康检查地址(默认 Tailscale HTTPS 域名) +# DEPLOY_TIMEOUT 等待超时秒数(默认 720;首次使用含旧 5 分钟 timer 周期余量) +# GIT_BRANCH 推送分支(默认 main) +# +# 用法:./deploy/deploy.sh + +set -euo pipefail + +HEALTH_URL="${DEPLOY_HEALTH_URL:-https://dify.taile5765c.ts.net/health}" +TIMEOUT="${DEPLOY_TIMEOUT:-720}" +BRANCH="${GIT_BRANCH:-main}" +POLL_INTERVAL=15 + +cd "$(dirname "$0")/.." + +echo "==> [1/3] 推送代码" +if [ -n "$(git status --porcelain)" ]; then + echo "⚠️ 存在未提交变更,请先 commit:" + git status --short + exit 1 +fi +git push origin "$BRANCH" +LOCAL=$(git rev-parse HEAD) +echo " 本地版本 ${LOCAL:0:8} 已推送,等待 cc1 自动更新…" + +echo "==> [2/3] 等待 cc1 更新(轮询 $HEALTH_URL)" +fetch_remote_commit() { + curl -s --max-time 10 "$HEALTH_URL" \ + | python3 -c "import json,sys; print(json.load(sys.stdin).get('commit',''))" 2>/dev/null || echo "" +} + +deadline=$(( $(date +%s) + TIMEOUT )) +REMOTE="" +while [ "$(date +%s)" -lt "$deadline" ]; do + REMOTE=$(fetch_remote_commit) + if [ "$REMOTE" = "$LOCAL" ]; then + echo " ✅ cc1 已更新至 ${LOCAL:0:8}" + break + fi + echo " 线上 ${REMOTE:0:8} | 目标 ${LOCAL:0:8},${POLL_INTERVAL}s 后重试…" + sleep "$POLL_INTERVAL" +done + +if [ "$REMOTE" != "$LOCAL" ]; then + echo "❌ 部署超时(${TIMEOUT}s 内 cc1 未更新至 ${LOCAL:0:8},当前线上 ${REMOTE:0:8})" + echo " 排查:ssh cc1 'journalctl -u vps-manager-update.service -n 30'" + exit 1 +fi + +echo "==> [3/3] 验证核心 API" +BASE="${HEALTH_URL%/health}" +FAILED=0 +for path in /api/assets /api/accounts /api/providers /api/stats/overview; do + code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$BASE$path" || echo "000") + if [ "$code" = "200" ]; then + echo " ✓ $path -> $code" + else + echo " ❌ $path -> $code" + FAILED=1 + fi +done + +if [ "$FAILED" -ne 0 ]; then + echo "❌ 部署后验证失败,请检查 cc1 服务日志" + exit 1 +fi +echo "🎉 部署完成:${LOCAL:0:8} 已在 cc1 生效并通过验证" diff --git a/deploy/update.sh b/deploy/update.sh index de66ae7..ab56fea 100644 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # vps-manager 自动更新脚本(由 systemd timer 定时触发) -# 从 Gitea 拉取最新代码,如有更新则重启服务 +# 1. 自动同步 deploy/ 下的 systemd 单元文件(有变更才拷贝 + daemon-reload) +# 2. 从 Gitea 拉取最新代码,如有更新则装依赖并重启服务 # # 可配置项(环境变量): # VPS_MANAGER_DIR 项目根目录(默认 /opt/vps-manager) @@ -28,6 +29,31 @@ print_version() { echo "[$(date '+%F %T')] 当前版本: v${semver} (${commit})" } +# 同步 systemd 单元文件:deploy/ 下的 .service/.timer 与 /etc/systemd/system +# 不一致时拷贝并 reload;timer 变更额外 restart 使新调度周期立即生效。 +# 每次都执行(而非仅版本更新时),保证单元变更不依赖代码变更触发。 +sync_units() { + local changed=0 f base + for f in "$APP_DIR"/deploy/*.service "$APP_DIR"/deploy/*.timer; do + [ -f "$f" ] || continue + base=$(basename "$f") + if ! cmp -s "$f" "/etc/systemd/system/$base"; then + cp "$f" "/etc/systemd/system/$base" + echo "[$(date '+%F %T')] 单元已更新: $base" + changed=1 + case "$base" in + *.timer) systemctl restart "$base" 2>/dev/null || true ;; + esac + fi + done + if [ "$changed" -eq 1 ]; then + systemctl daemon-reload + echo "[$(date '+%F %T')] systemd 单元同步完成" + fi +} + +sync_units + git fetch -q origin "$BRANCH" LOCAL=$(git rev-parse HEAD) diff --git a/deploy/vps-manager-update.timer b/deploy/vps-manager-update.timer index 41e080b..1a9ad62 100644 --- a/deploy/vps-manager-update.timer +++ b/deploy/vps-manager-update.timer @@ -1,4 +1,4 @@ -# vps-manager 自动更新定时器(每 5 分钟检查一次) +# vps-manager 自动更新定时器(每 1 分钟检查一次,配合 deploy.sh 实现准实时自动部署) # 部署位置:/etc/systemd/system/vps-manager-update.timer [Unit] @@ -6,7 +6,7 @@ Description=Periodic update check for vps-manager [Timer] OnBootSec=2min -OnUnitActiveSec=5min +OnUnitActiveSec=1min Unit=vps-manager-update.service [Install]