Blog部署演进之路

Blog从去年10月开始到现在已经过了大半年,总共经历了4次部署方式升级,最终也成功实现解放双手、完成自动化部署。下面来分享下四种部署方式的演变过程:

01、手动打包上传

最初Blog刚在本地调试完成,此时是通过hexo generate打包静态文件后,将public文件夹上传至阿里云OSS,之后给OSS绑定了域名来提供访问服务。

使用这种最原始的方式,每次部署大概需要花费2-3分钟。有时候还会因为OSS缓存导致页面不能及时刷新(所以后面是先删除全部文件,再执行上传)。
但优点是十分省钱,网站流量不高的时候一个月只花0.01-0.05元。

02、使用插件,打包后自动上传OSS

大概过了一段时间后,我在Hexo官网中发现了一款上传插件:hexo-deployer-cos-cdn。它需要在config.yaml中配置一些OSS参数:

1
2
3
4
5
6
7
8
9
10
11
12
# Deployment
# Docs: https://github.com/lxl80/hexo-deployer-cos-cdn
deploy:
type: cos-cdn
cloud: aliyun
bucket:
region:
secretId:
secretKey:
cdnEnable: false # 是否启用CDN加速,默认为 true,如果为 false ,将不会刷新 CDN 缓存。
deleteExtraFiles: false # 是否删除云端多余文件(本地不包含的文件),默认为 false,请谨慎选择。
updatePosts: false # 是否更新 Markdown 源文中的图片地址为CDN路径。默认为 false ,如果设置为 true ,之后再次修改 imageConfig.cdnUrl时,需要手动将 Markdown 源文中的图片地址批量替换为相对路径,否则不生效。

之后再将打包命令由hexo generate改为hexo generate -d,就可以实现打包后自动上传OSS。

改成这种方式后,每次部署大概需要花费1-2分钟。大约节省了30%的时间(该插件只会上传被修改的文件,但有时候会出现漏传的情况,需要注意一下!)。

03、迁移至ECS,定时从OSS内网同步

再之后,阿里云又推出了针对新老用户的99/年2C2G3M的ECS,忍不住手就上了车。

之后着手把Hexo从OSS迁移到了ECS,但是随即发现了一个问题:Hexo好像没有通过SSH部署啊?开SFTP上传又不太放心,于是想了一个歪招:在ECS上开了一个定时任务,每5分钟走内网拉取一次OSS文件

下面是示例的shell脚本:

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
#!/bin/bash

# 阿里云 OSS 相关信息
OSS_ENDPOINT="oss-cn-hangzhou-internal.aliyuncs.com"
OSS_BUCKET="****"
OSS_ACCESS_KEY_ID="****"
OSS_ACCESS_KEY_SECRET="****"

# 本地同步路径
LOCAL_PATH="/your_path"

# ossutil 路径
OSSUTIL_PATH="/home/ossutil"

# 清空本地目录
rm -rf "${LOCAL_PATH}"/*

# 检查 ossutil 是否已安装
if [ ! -f "${OSSUTIL_PATH}" ]; then
echo "ossutil not found. Downloading and installing..."

# 检查是否安装 unzip
if ! command -v unzip &> /dev/null; then
echo "unzip not found. Installing unzip..."
sudo yum install -y unzip
echo "unzip installed successfully."
fi

OSSUTIL_DOWNLOAD_URL="https://gosspublic.alicdn.com/ossutil/1.7.18/ossutil-v1.7.18-linux-amd64.zip"
curl -o /tmp/ossutil.zip "${OSSUTIL_DOWNLOAD_URL}"

# 解压缩
unzip /tmp/ossutil.zip -d /tmp/

# 找到解压缩后的文件夹中的可执行文件
OSSUTIL_EXECUTABLE=$(find /tmp/ossutil* -type f -name "ossutil64")

# 移动可执行文件到指定路径
mv "${OSSUTIL_EXECUTABLE}" "${OSSUTIL_PATH}"

chmod +x "${OSSUTIL_PATH}"
rm /tmp/ossutil.zip
echo "ossutil installed successfully."
fi

# 同步命令
SYNC_COMMAND="${OSSUTIL_PATH} cp -r oss://${OSS_BUCKET}/ ${LOCAL_PATH} -i ${OSS_ACCESS_KEY_ID} -k ${OSS_ACCESS_KEY_SECRET} -e ${OSS_ENDPOINT}"

# 执行同步命令
${SYNC_COMMAND}

改成这种方式后,部署时间没有变化,但是可以自动把文件从OSS同步到ECS里,也顺带解决了缓存不能及时更新的问题(缓存问题主要是ECS中配置nginx网站策略更方便一些)。

04、Gitea Action自动化部署

在使用了一段时间的ECS后,将Hexo项目从本地自建Gitlab迁移至ECS的Gitea中,这样可以使用gitea的act_runner来实现类似Github Action的自动化构建任务。

下面是示例的Gitea Action脚本:

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
name: Hexo Build Task Example
on:
push:
branches:
- main

jobs:
Develop-Build-And-Deploy:
runs-on: ubuntu-latest
container:
image: node:14
volumes:
- /hexo:/workspace/deploy
steps:
- name: Checkout Repository
uses: https://gitea.com/actions/checkout@v3
- name: Install Npm Package
run: |
npm config set registry https://registry.npmmirror.com/ --global
npm install
- name: Build Hexo
run: |
hexo generate
- name: Clean Deploy Folder
run: |
rm -rf /workspace/deploy/*
- name: Deploy Hexo
run: |
cd ./public
cp -r "./" "/workspace/deploy"

主要注意点有这几个:

  • 需要在volumes中把网站目录映射到task容器下的目录(通过docker volume形式);
  • checkout步骤时使用 https://gitea.com/actions/checkout@v3 可以提升拉取速度;
  • 每次部署时清空 /workspace/deploy 目录(如果每次部署都是增量更新,就会出现废弃资源一直冗余的情况);

改成这种方式后,本地只需要执行Push操作,后续操作将由.gitea/workflow目录下的工作流文件来接管,非常省心。整个打包部署时长大约在1分钟左右。(具体得看服务器的性能)

05、结尾

从最初的手动打包上传到最后自动化部署,笔者经历了将近半年时间。在过去的实践经历中,笔者对自动化的经历最多就是使用docker compose来部署开发、生产环境,这是首次体验到自动化部署项目的快乐,非常nice!
本文其实还有一个小章节,笔者已经预先写好了一个Gitea Action任务,可以通过输入url、category、slug等字段,拉取远程文档并编译发布至Blog。但Gitea Action目前还不支持on: workflow_dispatch的方法,导致目前还无法使用,所以此文也未提到该部分内容。

关于 on: workflow_dispatch 的支持,可以密切关注下面这个提交!
Actions support workflow dispatch event


评论区