Skip to content

Commit d02f867

Browse files
committed
优化网站部署流程:简化目录布局与 symlink 方案
1 parent 371d204 commit d02f867

2 files changed

Lines changed: 38 additions & 44 deletions

File tree

.github/workflows/deploy_website.yml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,26 @@ jobs:
4242
chmod 600 ~/.ssh/deploy_key
4343
ssh-keyscan -p "${{ secrets.DEPLOY_PORT || '22' }}" -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null
4444
45-
- name: Rsync dist to server incoming/
45+
- name: Rsync dist to server (.incoming)
4646
env:
4747
PORT: ${{ secrets.DEPLOY_PORT || '22' }}
4848
USER: ${{ secrets.DEPLOY_USER }}
4949
HOST: ${{ secrets.DEPLOY_HOST }}
50+
# DEPLOY_PATH = 站点 index 目录,例如 /opt/1panel/www/sites/zap.zerx.dev/index
5051
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
5152
run: |
52-
# 确保远端目录存在
53+
# 在站点父目录(index 的上一级)准备暂存区与脚本目录
54+
PARENT="$(dirname "$DEPLOY_PATH")"
5355
ssh -i ~/.ssh/deploy_key -p "$PORT" "$USER@$HOST" \
54-
"mkdir -p '$DEPLOY_PATH/incoming' '$DEPLOY_PATH/deploy'"
55-
# 推送静态产物(--delete 保证 incoming 与本地 dist 完全一致)
56+
"mkdir -p '$PARENT/.incoming'"
57+
# 推送静态产物到 .incoming(--delete 保证与本地 dist 完全一致)
5658
rsync -az --delete \
5759
-e "ssh -i ~/.ssh/deploy_key -p $PORT" \
58-
dist/ "$USER@$HOST:$DEPLOY_PATH/incoming/"
59-
# 推送部署脚本
60+
dist/ "$USER@$HOST:$PARENT/.incoming/"
61+
# 推送部署脚本到父目录
6062
rsync -az \
6163
-e "ssh -i ~/.ssh/deploy_key -p $PORT" \
62-
deploy/deploy.sh "$USER@$HOST:$DEPLOY_PATH/deploy/deploy.sh"
64+
deploy/deploy.sh "$USER@$HOST:$PARENT/deploy.sh"
6365
6466
- name: Run remote deploy script
6567
env:
@@ -68,9 +70,11 @@ jobs:
6870
HOST: ${{ secrets.DEPLOY_HOST }}
6971
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
7072
run: |
71-
# 远端赋予执行权限并运行,避免 pull/上传后无执行权限的问题
73+
# 远端赋予执行权限并运行,把正式 index 目录作为参数传入
74+
# 避免 pull/上传后无执行权限的问题:每次都 chmod +x
75+
PARENT="$(dirname "$DEPLOY_PATH")"
7276
ssh -i ~/.ssh/deploy_key -p "$PORT" "$USER@$HOST" \
73-
"chmod +x '$DEPLOY_PATH/deploy/deploy.sh' && '$DEPLOY_PATH/deploy/deploy.sh'"
77+
"chmod +x '$PARENT/deploy.sh' && '$PARENT/deploy.sh' '$DEPLOY_PATH'"
7478
7579
- name: Cleanup SSH key
7680
if: always()

website/deploy/deploy.sh

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,40 @@
11
#!/usr/bin/env bash
22
# Zap 官网部署脚本(在服务器上执行)
33
#
4-
# 由 GitHub Actions 上传到 $DEPLOY_PATH/deploy/deploy.sh 后,经 chmod +x 远程执行。
5-
# 职责:把上传好的静态产物(dist/)切换为对外服务目录,做原子发布 + 保留回滚。
4+
# 场景:站点由 1Panel 托管,nginx root 固定指向站点目录(例如
5+
# /opt/1panel/www/sites/zap.zerx.dev/index),无法改 root 用 symlink 方案。
6+
# 故这里做"原子目录替换":CI 已把最新产物 rsync 到 <site>/.incoming,
7+
# 本脚本把 .incoming 重命名为正式 index 目录,并保留上一版用于回滚。
68
#
7-
# 约定的目录布局($DEPLOY_PATH 下):
8-
# incoming/ ← Actions 用 rsync 推上来的最新 dist 内容
9-
# releases/<ts>/ ← 每次发布的快照
10-
# current ← symlink,指向当前生效的 releases/<ts>(nginx root 指这里)
11-
#
12-
# nginx 的 root 应配置为 $DEPLOY_PATH/current
9+
# 约定布局($DEPLOY_PATH = 站点 index 目录,例如 .../zap.zerx.dev/index):
10+
# <parent>/.incoming ← CI rsync 推上来的最新 dist 内容
11+
# <parent>/index ← nginx 实际服务的目录(= $DEPLOY_PATH)
12+
# <parent>/.index.bak ← 上一版,用于回滚
1313
set -euo pipefail
1414

15-
# 部署根目录:脚本位于 <root>/deploy/deploy.sh,故根目录是脚本上两级
16-
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
17-
INCOMING="$ROOT/incoming"
18-
RELEASES="$ROOT/releases"
19-
CURRENT="$ROOT/current"
20-
KEEP=5 # 保留最近多少份 release 用于回滚
15+
# $DEPLOY_PATH 由调用方(SSH 命令)以第一个参数传入,即正式 index 目录
16+
INDEX="${1:?用法: deploy.sh <site-index-dir>}"
17+
PARENT="$(dirname "$INDEX")"
18+
INCOMING="$PARENT/.incoming"
19+
BACKUP="$PARENT/.index.bak"
2120

2221
log() { printf '[deploy] %s\n' "$*"; }
2322

2423
if [ ! -d "$INCOMING" ] || [ -z "$(ls -A "$INCOMING" 2>/dev/null)" ]; then
25-
log "错误:$INCOMING 不存在或为空,没有可发布的产物先由 CI rsync 产物到 incoming/"
24+
log "错误:$INCOMING 不存在或为空,没有可发布的产物(先由 CI rsync 到 .incoming)"
2625
exit 1
2726
fi
2827

29-
TS="$(date +%Y%m%d%H%M%S)"
30-
TARGET="$RELEASES/$TS"
31-
32-
mkdir -p "$RELEASES"
33-
log "创建发布快照:$TARGET"
34-
# 用 cp -a 从 incoming 物化一份不可变快照,保证 current 切换是原子的
35-
cp -a "$INCOMING" "$TARGET"
36-
37-
# 原子切换 current symlink:先建临时 link 再 rename,避免出现短暂无 current 的窗口
38-
log "切换 current -> releases/$TS"
39-
ln -sfn "$TARGET" "$CURRENT.tmp"
40-
mv -Tf "$CURRENT.tmp" "$CURRENT"
28+
# 删除上一版备份,把当前 index 移为备份(若存在)
29+
if [ -e "$INDEX" ]; then
30+
log "备份当前版本 -> $BACKUP"
31+
rm -rf "$BACKUP"
32+
mv -Tf "$INDEX" "$BACKUP"
33+
fi
4134

42-
# 清理旧 release,保留最近 $KEEP 份
43-
log "清理旧 release,保留最近 $KEEP"
44-
cd "$RELEASES"
45-
ls -1dt */ 2>/dev/null | tail -n +$((KEEP + 1)) | while read -r old; do
46-
log " 删除 $old"
47-
rm -rf "${RELEASES:?}/${old%/}"
48-
done
35+
# 原子上线:rename .incoming -> index(同一文件系统,mv 为原子操作)
36+
log "发布新版本 -> $INDEX"
37+
mv -Tf "$INCOMING" "$INDEX"
4938

50-
log "完成。current 现指向:$(readlink -f "$CURRENT")"
39+
log "完成。当前服务目录:$INDEX"
40+
log "如需回滚:rm -rf '$INDEX' && mv -Tf '$BACKUP' '$INDEX'"

0 commit comments

Comments
 (0)