Hugo自动化部署(GitHub->阿里云)
写作完成后push到GitHub,触发Actions构建站点,上传到阿里云OSS,实现无感自动发布

最近更换了博客系统,从WordPress迁移到了Hugo,按照我们程序员的传统,搭建博客之后把搭建过程记录下来是重中之重,怎么都不能错过这个给文章数量+1的机会。

至于为什么要进行迁移,我上一篇文章已经做了解释,这里就不再赘述了。今天我们主要关注如何实现自动发布,也就是写完文章之后,push到仓库,然后Github Actions自动识别到你的更新,构建出静态文件,接着将静态文件上传到阿里云OSS的Bucket中,实现发布的能力。

创建和配置Bucket

静态站点的html、css、js和图片等都是放在Bucket里的,阿里云的存储是付费的,存储的费用大概在0.12元每月每GB,流量费用大概在0.5元每GB,就博客的体量来说,花不了多少钱,我看了看我的博客之前的流量,每月大概2GB,一个月就1元流量费,一年成本20元封顶了。本来还想试用CDN,想想没必要,还是不折腾了。阿里云上Bucket的申请还是比较简单的,以下是创建的界面:

地域你根据自己的情况来,不同的地域的Endpoint(即地域节点)不一样,这个Endpoint在后面有用到。然后读写权限搞成公共读,毕竟资源都是公开访问的。其他的配置项按照默认的来就行,如果你懂点就按照自己的需求来。请忽略我填写的Bucket名。

Bucket有了,然后需要微微配置一下,告诉阿里云我的这个Bucket是用来搭建静态站点的。你需要打开Bucket的管理页面,找到静态页面的配置项,如图所示:

在默认情况下,如果你访问站点的根路径时,OSS会返回给你一个错误页面,通常情况下我们希望访问静态站点的某个路径的时候,OSS返回路径下的index.html,这样就能在浏览器上显示内容了,同时地址栏上显示某个路径,而不是具体的文件名,地址栏上显示.html扩展会显得多余,虽然也可以访问。所以“默认首页”需要填上index.html,子目录也保持同样的行为。

如果没有找到对应的资源,就会报错,为了保持体验,你需要搞个专门的404页面来处理没有找到资源的情况。设置页面上也有描述每个设置项的作用,写的很清楚,你如果懒得弄懂,就照着我的配好了。

域名和证书的设置

通过OSS默认域名访问html等静态资源的时候,浏览器会自动当成文件下载,而不是直接在页面中加载。设置完自定义域名之后,就可以作为页面正常访问了。这是设置页面:

设置分为两部,第一步是验证域名的所有权,另一步是添加CNAME记录,就是将你的域名映射到默认域名。这里的验证和添加,都是到你的域名解析提供商那里进行配置。因为我把域名将解析放到了阿里云的云解析,我输入域名之后,它就自动识别了所有权,并且可以自动添加CNAME记录,所以几秒钟就搞定了,很方便。

接下来就是配置SSL证书了。当然你也可以不用,反正也没人会去攻击你UV为5的静态的没有表单的自嗨站,不过证书也确实可以帮助你避免运营商的页面广告注入。作为专业人士,应该把https作为一种习惯,这是一种意识。阿里云每年有20个免费证书可以申领。之前证书时效是1年,现在变成3个月了,有点麻烦。

在申请证书的时候,也是需要进行验证的,就是搞个DNS记录,如果你的域名是放在云解析的,可以自动进行DNS验证,不用自己手动去填写了。有了证书再将证书配置到Bucket,找到刚才配置自定义域名的地方,点击“证书托管”,选择你刚才申请的证书就可以了。你也可以上传在其他地方申请的证书,不麻烦。

如果你的域名解析是在云解析的,整个过程还是非常方便的,可能2分钟就搞定自定义域名和证书配置了。就算你的域名是在其他地方解析的,证书是在其他地方购买的,也可以轻松完成整个配置流程。

简单验证

在Bucket中随便上传一个index.html文件,访问你的域名,就可以浏览静态站点了。

接下来我们看看如何将静态资源文件自动上传到Bucket。

Github仓库的配置

创建个仓库,用来保存你的文章源码。

因为流水线在运行的时候,需要权限才能将文件上传到Bucket。首先,你需要在阿里云上创建一个RAM 用户,授予它AliyunOSSFullAccess权限,这样RAM用户就能访问OSS了,你有空的话,可以将这个权限设置的粒度设置更小一点,比如只授权某个Bucket的读写权限,遵循最小权限原则。然后生成这个用户的AccessKey,这个是用来完成API操作的。

对于Bucket的访问你需要在仓库上配置以下四个数据:

  • OSS_BUCKET: Bucket的名称

  • OSS_ENDPOINT: 上面提到的和区域相关的Endpoint

  • OSS_ACCESS_KEY_ID: AccessKey的ID

  • OSS_ACCESS_KEY_SECRET: AccessKey的Secret

这些敏感数据,放到代码仓库里不太安全,Github提供了在仓库里配置敏感信息的能力,可以配置流水线专用的secret:

添加secret之后,就可以在流水线中通过secret的名称访问secret的值了。

流水线的创建

Github Actions是Github推出的自动化工作流工具,主要用来完成CI/CD。它的工作流是通过yaml文件定义的,放在仓库的.github/workflow目录下。如果你没有空去看Github的文档来看yaml文件格式的定义,那么直接看下面的代码,我把它命名为publish.yml

就算你之前没有接触过Github Actions,你也大概能从下面的文件中看出工作流的运行环境和步骤,比如用的系统是ubuntu最新版。在工作流的执行步骤中,我额外使用了两个Github Actions插件,一个是hugo-setup,它会把Hugo的环境准备好,这样就能在运行环境中执行hugo命令了。另一个插件是setup-ossutil,它会把OSS命令准备好,同时把secrets中需要的参数传递给命令。

name: 发布博客

on:
  push:
    branches: ["main"]
  workflow_dispatch:

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: 安装Hugo环境
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'
          extended: true

      - name: 下载代码
        uses: actions/checkout@v4
        with:
          submodules: true
          fetch-depth: 0

      - name: 构建
        run: hugo --minify

      - name: 配置阿里云OSS 
        uses: manyuanrong/setup-ossutil@v3.0
        with:
          endpoint: ${{ secrets.OSS_ENDPOINT }}
          access-key-id: ${{ secrets.OSS_ACCESS_KEY_ID }}
          access-key-secret: ${{ secrets.OSS_ACCESS_KEY_SECRET }}

      - name: 上传资源
        run: |
          ossutil rm -rf oss://${{ secrets.OSS_BUCKET }}
          ossutil cp -rf public oss://${{ secrets.OSS_BUCKET }}

除了这两个工具,剩下的都是正常的步骤了。构建的时候会用hugo --minify命令,将静态资源的大小压缩,类似于UglifyJS。构建之后的文件在public目录中,在最后一步执行上传资源的时候,分为两部分,首先是把旧的资源删除,然后再把public中新构建出来的资源上传到Bucket中。为什么要删除旧的资源?我是受不了网站里放之前版本的无效资源,而且日积月累可能会不断增加空间的占用,导致费用的增加,虽然静态资源并没有多大。

跑通发布流程

你把流水线的配置文件添加到仓库里之后,push下代码,流水线就可以执行了。你自己在操作的时候多少会出现一些问题,不过看看错误报告基本都能很快解决。

整个流程还真是挺顺畅的,在我自己操作历史中,整体流程平均只需要25s就能完成了。其中上传资源只用了3s,我原以为GitHub和阿里云的数据交互会占用比较长的时间。这样的话在很长一段时间里,发布时间都不会超过1分钟。希望本文能帮助你快速搭建起自己的博客和自动发布流水线。


最后修改于 2024-03-03