Xz's blog Xz's blog
首页
时间序列
多模态
合成生物学
其他方向
生活
工具相关
PyTorch
导航站

Xu Zhen

首页
时间序列
多模态
合成生物学
其他方向
生活
工具相关
PyTorch
导航站
  • 博客相关

    • VuePress 部署服务器
    • GitHub Action 自动化部署网站
      • 初始方案
      • 进阶方案
    • 使 VuePress 支持图片中包含中文字符
    • 使 VuePress 支持公式
    • Vdoing-VuePress 支持 webp 格式图片
  • 生活
  • 博客相关
xuzhen
2025-07-02
目录

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

其中有几个私密变量需要我们提前设置一下: 这样在我们将博客 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
#VuePress
上次更新: 2025/07/05, 22:15:22

← VuePress 部署服务器 使 VuePress 支持图片中包含中文字符→

最近更新
01
Slice切片
07-26
02
引用与借用
07-26
03
所有权
07-26
更多文章>
Theme by Vdoing | Copyright © 2025-2025 Xu Zhen | 鲁ICP备2025169719号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式