GitHub Action 自动化部署网站
# 初始方案
当前博客使用的 VuePress 的 Vdoing (opens new window) 主题,VuePress 是一个以 Markdown 为中心的静态网站生成器。我们需要将 VuePress 生成的静态网站部署到自已的服务器上才能供其他人访问,但是每次写完文章自己手动部署十分麻烦。为了简化这个过程,这就需要使用 GitHub 的 Action 功能,来帮我们自动化的生成静态文件,并上传到服务器上。 下面是当前博客使用的 Action:
name: CI
# 当 master 分支发生 push 事件时触发
on:
push:
branches:
- master
env: # 设置环境变量
TZ: Asia/Shanghai # 设置时区为北京时间
jobs:
build: # 自定义任务名称
runs-on: ubuntu-latest # 运行在 ubuntu 虚拟环境
strategy:
matrix:
node-version: [22.14.0] # 使用 Node.js 18.x 版本
steps:
- name: Checkout # 步骤1:检出代码
uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }} # 步骤2:安装 Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Build-and-deploy # 步骤3:构建并部署到远程服务器
run: |
# 创建 .ssh 目录并设置权限
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 配置 SSH 私钥
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# 禁用主机密钥检查(可选,避免未知主机问题)
echo "StrictHostKeyChecking no" >> ~/.ssh/config
# 安装依赖并构建
# yarn
# yarn build
# 使用 npm 安装依赖并构建
npm install
npm run build
# 配置远程服务器信息
remote_user="${{ secrets.NAME }}" # 替换为你的远程服务器用户名
remote_host="${{ secrets.IP }}" # 替换为你的远程服务器 IP 地址或域名
remote_port="22" # 替换为你的远程服务器 SSH 端口(默认 22)
remote_path="/var/www/xzxz.top" # 替换为你的远程服务器目标路径
# 打包后的文件路径
build_path="docs/.vuepress/dist"
# 压缩打包文件
echo "压缩打包文件..."
tar -czf site.tar.gz -C $build_path .
echo "压缩完成,文件大小:"
ls -lh site.tar.gz
# 创建远程目录并清空
echo "创建远程目录并清空"
ssh -p $remote_port $remote_user@$remote_host "mkdir -p $remote_path && rm -rf $remote_path/*"
# 传输压缩文件到远程服务器
echo "开始传输压缩文件到远程服务器..."
scp -P $remote_port site.tar.gz $remote_user@$remote_host:$remote_path/
# 在远程服务器解压文件
echo "在远程服务器解压文件..."
ssh -p $remote_port $remote_user@$remote_host "cd $remote_path && tar -xzf site.tar.gz && rm site.tar.gz"
echo "部署完成!"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
其中有几个私密变量需要我们提前设置一下:
这样在我们将博客 Push 到 GitHub 时,GitHub 会 Action 自动将我们的博客打包并复制到服务器上。
# 进阶方案
上面代码的问题是:先清空了原来的静态网站文件夹,再传输新的资源。这会导致 3 分钟的网站无法访问。
为了最小化网站更新时的访问影响,即实现“无缝部署”效果。常见方法是先上传到临时目录,解压完成后再原子性地切换目录(比如用软链接 ln -sfn
),这样切换几乎不会中断访问。
name: CI
on:
push:
branches:
- master
env:
TZ: Asia/Shanghai
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [22.14.0]
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Build-and-deploy
run: |
# SSH 配置
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "StrictHostKeyChecking no" >> ~/.ssh/config
# 构建
npm install
npm run build
# 路径配置
remote_user="${{ secrets.NAME }}"
remote_host="${{ secrets.IP }}"
remote_port="22"
production_path="/var/www/xzxz.top" # 软链
releases_dir="/var/www/xzxz.top_releases" # 所有版本父目录
build_path="docs/.vuepress/dist"
# 打包
release_name="release-$(date +%Y%m%d%H%M%S)"
tar_file="$release_name.tar.gz"
tar -czf $tar_file -C $build_path .
# 上传和部署
ssh -p $remote_port $remote_user@$remote_host "
mkdir -p $releases_dir
"
scp -P $remote_port $tar_file $remote_user@$remote_host:$releases_dir/
ssh -p $remote_port $remote_user@$remote_host "
set -e
cd $releases_dir &&
mkdir $release_name &&
tar -xzf $tar_file -C $release_name &&
rm $tar_file &&
ln -sfn $releases_dir/$release_name $production_path &&
# 保留最近3个 release 目录,删除更早的
ls -dt $releases_dir/release-* | tail -n +4 | xargs -r rm -rf
"
echo "部署完成,已无缝切换到新版本,仅保留最近3个发布版本!"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
上次更新: 2025/07/05, 22:15:22