ChrAlpha's Blog

初探无后端静态博客自动化部署方案

2020-02-14·笔记本

与 Hexo 同样,Hugo、Vuepress 等都属于「无后端静态博客」阵容。而部署流程也不外乎在本地利用环境生成静态资源并上传网页目录,托管于不同服务。

而如果我们希望能够在一台陌生设备上迅速「恢复状态」,则需要:

  • 利用本地搭建好的环境生成 网页目录 并上传部署
  • 同步 博客源码 至云端方便异地协作
img

好像也不麻烦?

但是在每一台设备上都绕不过恼人的环境配置。

更何况,能一步做好的,为什么要两步?!

期望

我们设想以下场景:

  • 使用 GitHub 私有仓库 blog 存放博客源码
  • 使用 GitHub 公共仓库 website 存放网页目录

我们的预期是,将网站更新后的源码推送到 blog 时,能够自动检测更新并且重新部署到 website 中。

img

也就是说,只有红色部分是需要我们手动完成的,其余的(蓝色部分)则交给自动化。

Netlify

Netlify 是一家位于旧金山的云计算公司,为静态网站提供托管服务。同时拥有免费和付费的服务可供选取,免费额度目前为 300 分钟每月的计算时长限制和 100 GB 每月的流量限制,超出都会索取一定费用。关于不同套餐之间的功能和限制可以参考 官方页面

计算资源方面与 GitHub Action 相比有点「节约」,一次更新大概是需要 1 分钟左右的部署,一个月约 300 次的更新也还算充裕。如果需要调试页面还是建议就放在本地执行。

部署操作

Netlify 部署的流程也很简单,我们详细的来看一下。

首先自然是使用 GitHub 账号登陆,然后来到主页,点击 New site from Git

img

紧接着选择从 GitHub 获取,会让你授权,并不需要将所有 repositories 都授权给 Netlify,即便是私有仓库也没问题。

img

注意这里,建议只将需要部署的仓库授权给 Netlify 而非全部仓库:

img

之后就可以配置部署的设置了。需要注意:Build command 指的是构建,也就是生成网站源码所使用的命令;而 Publish diretory 则为生成的网页目录的位置。此外我们还可以调整默认部署的分支和拥有者(免费版暂不支持多账号协作)。

img

点击 Deploy site ,稍微等待一会你的网站就部署好了。可以前往设置更改 site-name ,默认域名为 site-name.netlify.com ,你也可以绑定自己的域名,Netlify 使用 Let’s Encrypt 提供的免费证书进行 HTTPS 部署。

自动更新

待上述步骤完成,不出意料我们已经可以访问网站了。

现在尝试一下添加 post,将其直接推送到 Blog 仓库中。

hexo new "Hello Netlify"

# ------------------------------
## Editing the post
# ------------------------------

git add .

git commit -m "add post"

git push

再回到 Netlify 页面,发现 Netlify 已经成功监测到 repository 变动并自动开始了新的部署。不一会,就已看到新的页面上线了。

img

小结

Netlify 凭借足够简易的操作逻辑,以及可观的免费额度,确实值得考虑。

另外, Netlify 提供全球 CDN 支持,即便是免费账户也可以享受更快的访问速度,这一点较 GitHub Page 在体验上确实加分不少。

Vercel

Vercel 也是一家提供免费静态托管的云服务云计算公司。相较于 Netlify,他的线路对中国大陆用户更加友好。免费版流量限制,与 Netlify 相同,均为 100G,而部署次数为每日 100 次。更多限制请参考 官方文档

部署方法和 Netlify 类似,仅需关联仓库后便会自动处理每一次 Push 和 Pull Request。更贴心的是,Vercel 内置了大多网站生成工具的处理工作流,只需要一个开关便可全自动处理。详细流程不再赘述。

Vercel 内置 Hexo 部署方式

SSL 错误处理

相信大多数用户使用 Vercel 托管网站都会绑定自己的域名,但是如果你的域名使用 Cloudflare 解析,并且开启 CDN 的话,需要单独允许 HTTP 访问 /.well-known/* 目录。

方法来源于 Vercel 官方文档:How do I use a Cloudflare domain with Vercel?

为此,需要关闭「SSL/TLS => Edge Certificates」中的 Always Use HTTPSAutomatic HTTPS Rewrites,并配置 Page Rules 单独放行 /.well-known/* 目录并让其他目录总是使用 HTTPS。

Cloudflare Page Rules 配置

注意两条优先级顺序,不要让 Always use HTTPS 覆盖特定目录的 Disable Security

其实,Vercel 线路已经很优秀了,再套一层 Cloudflare 不一定能体现加速的效果。

GitHub Actions

GitHub Actions 允许使用者构建持续集成与持续部署管道来测试、发布、搭建软件而无需借助第三方平台。持续集成由许多操作组成,如抓取代码、运行测试、发布等,GitHub 将其统称为 Actions。

借助这个特性,我们也可以让 GitHub Actions 来帮助我们部署网页。

GitHub 继续维系大厂作风,免费额度可以说是「慷慨」。6 小时的连续计算时长限制,而总时长则不设限。这点可以说是碾压 Netlify 的免费额度。

而在 GitHub Action 里,有这样几个基本的「单位」:

  1. workflow:一个持续集成的过程,就是一个 workflow 。
  2. jobs:一个 workflow 可以同时完成多个 jobs,每个 job 独立完成,互不干扰。
  3. steps:每个 job 可以包含多个 steps,一步步完成。
  4. actons:每个 step 可以执行多个 action 。action 可以理解为一条条命令,是 GitHub Actions 中最小的单位。

且 GitHub Actions 为每个 Job 提供一个独立的虚拟环境运行,都拥有相同的硬件资源:

  • 2 核 CPU
  • 7 GB RAM 内存
  • 14 GB SSD 硬盘

关于 限制收费 可以参考 GitHub Actions 的 Wiki 。

部署操作

废话不多说,赶紧看看如何使用。

首先我们要生成一个 SSH 密钥,方便 GitHub Action 上传网页目录到我们的 repository 。

ssh-keygen -t rsa

公钥添加到存放网页目录的 GitHub 账号「Settings - SSH and GPG keys」内;将私钥添加到你博客源码仓库的「Settings - Secret」内,起一个名字,例如我让他叫 HEXO_DEPLOY_KEY

之后就是新建一个 Workflow。点击 GitHub 仓库控制栏中的 Actions,选择新建一个,并将下面的代码替换掉原来的代码。

img
name: Hexo Deploy Automatically

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - name: Checkout
        uses: actions/checkout@v2
        
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      
      - name: Generate
        run: |
          npm i && npx hexo g
      
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_branch: gh-pages
          publish_dir: ./public
          cname: blog.ichr.me
          force_orphan: true

这份代码究竟在做什么:

  • 最上方 name 是整个 workflow 的名字;紧接着的 on 参数指的是触发调节,比如我们这里使用 push 来触发,每次监测到仓库被 push 了就运行此 workflow。
  • 接下来就是 jobs 。我创建一个名为 build 的 job,runs-no(运行在)最新版的 ubuntu 系统里。
  • 里面的 steps(步骤)有:checkout 引入调用自身仓库的插件;Node.js envs 调用 Node.js 搭建环境;Generate 生成网页;Deploy 部署到当前仓库的 gh-pages 分支。

将代码中的部分信息更新为自己的,就可以尝试更新 push 一下了!

img

小结

最「原生」的支持,实在慷慨的计算资源,(几乎)可以忽略的限制。这些,都或许是你选择 GitHub Actions 的理由。

虽说是持续集成,实则是用完即毁。所以每次都是崭新的环境,需要重新安装各项依赖。只不过这些都不用本地执行,第一次配置好了之后也完全不用再操心。

每次 push 完后需要大概十几秒的等待才能部署(个人感觉还是快于 Netlify),debug 也还是建议先在本地调试再上传。

但是我在使用 GitHub Actions 构建的时候,所有文章的「更新时间」都会变为最后一次构建的时间。暂时没有找到什么比较好的解决方案,只好在每篇文章的 Front-matter 中加入 updated 这个参数了。

Travis CI

和 GitHub Actions 类似,Travis CI 也提供持续集成服务。同时 Travis CI 还是同类型服务商中市场份额最高的,在 GitHub Actions 诞生之前一直是最受欢迎的持续集成服务商(之后或许也是)。

目前 Travis CI 只面向 GitHub 提供服务,也就是说只有将代码托管到 GitHub 仓库才能享受到 Travis CI 提供的服务。

GitHub Actions 所有 workflow 都是以文件的形式保存的,Travis CI 也是如此。Travis CI 会根据根目录下的 .travis.yml 来执行相应工作流。

一个 Travis 完整的工作流程包括:

  1. language(设置环境)
  2. before_install
  3. install
  4. before_script
  5. script
  6. aftersuccess or afterfailure
  7. [OPTIONAL] before_deploy
  8. [OPTIONAL] deploy
  9. [OPTIONAL] after_deploy
  10. after_script

都是使用命令执行,只不过不同流程中对于命令之间的逻辑关系处理的不太一样。

install 类中有:

install: 
  - command 1
  - command 2

command 1 失败后整个构建就会停下来,command 2 也就不再执行。

而对于 script 一类的:

script: 
  - command 1
  - command 2

就算 command 1 失败,command 2 也会继续执行。但是整个构建状态还是会返回失败。

部署步骤

我们前往 Travis CI 官网 使用 GitHub 账号登陆,根据提示授权。

出于安全考量,GitHub 肯定不会允许一个陌生容器将内容推送到自己的仓库中。我们需要使用一种特殊的手段给 Travis CI 授权——Access Token 。Access Token 可以理解为一个口令,当 Travis CI 使用这个口令和 GitHub 对接的时候,GitHub 就能知道是否应该给予 Travis CI 权限以及应开放哪些权限。

在 GitHub 账号中「Settings - Developer settings - Personal access tokens」中新建一个 token 。注意这里的 token 应考虑一下是否需要保存下来,token 只会出现一次!

之后回到 Travis CI,选择添加仓库,将博客源码的仓库对应按钮点亮,并点击后面的 settings 进入更深入的设置。

img

这里的 Environment Variables ,类似 GitHub 中的 secret ,可以保存一些不便公开的参数,如 Access Token 等,方便仓库开源和后续的调用。如果不想公开 GitHub 的用户名和邮箱,也可以在放入这里。

img

然后是配置 .travis.yml 文件:

language: node_js

node_js:
  - lts/*

cache:
  directories:
    - node_modules

before_install:
  - npm i -g hexo-cli
  
install:  
  - npm i
  - npm i -S hexo-deployer-git

script:
  - hexo clean
  - hexo generate

after_script:
  - git config --global user.name "${GH_Name}"
  - git config --global user.email "${GH_Email}"
  - sed -i 's/git@github.com/https://${HEXO_DEPLOY_TOKEN}@github.com/g' ./_config.yml 
  #如果配置文件中是使用 https 推送的,则上述命令改为:
  #- sed -i 's/github.com/${HEXO_DEPLOY_TOKEN}@github.com/g' ./_config.yml 
  - hexo deploy

branches:
  only:
    - master

代码也不难理解。最上方为设置在 Node.js 环境下运行,并且设置为获取最新版本的 Node.js 。由于 node_modules 目录体积较大且后期维护时修改频率很低,所以我们将其缓存以加快更新速度。再往下就是正常的安装和部署命令了。

小结

Travis CI 老牌且强大,可就我短时间体验来看感觉不如 GitHub Actions 来的那般方便。而且 Travis CI 仅支持公开的仓库,如果想在私有仓库上也启用则需要购买 商业版(前 100 次试用免费,价格略贵)。也算是一种方案,只是已经不是很推荐了。

Netlify 适合不愿在配置上花费太多功夫的用户,我在这里也近乎将其部署流程每一步都提及了。确实,放到一起来看 Netlify 学习成本几乎为零,任何人都能立马上手。

GitHub Actions 和 Travis CI 则需要一定的代码能力(一点点就好),能够理解 Workflow 便能很快的构建好自己的工作流。

如果再进一步,设置一个十分简单的推送脚本(go.sh):

echo "Well done. Keep going!"
git add .
git commit -m "$1"
git push

那一切的一切都只需要 sh go.sh "commit message" 一行解决。

但这些方案终究只是减少你在重复行为上花费的时间,让你能够集中精力在更有意义的事情上。最重要的还是赶紧把你的 Ideas 记下来、说出来,让更多的人了解你的想法。希望你能有所收获!


参考链接

初探无后端静态博客自动化部署方案
本文作者
ChrAlpha
发布日期
2020-02-14
更新日期
2020-10-07
转载或引用本文时请遵守 CC BY-NC-SA 4.0 许可协议,注明出处、不得用于商业用途!
CC BY-NC-SA 4.0