之前本博客的源码是存放在 GitHub,托管在 Vercel 中。我只需在本地编写文章,编写完毕后将文章提交到 GitHub 仓库中。Vercel 可以监控 GitHub 仓库的变化,当仓库有更新时,Vercel 会读取仓库内容,自动执行编译操作,并更新博客网站。
之前在腾讯云购买了三年的轻量应用服务器,为了把这台服务器利用起来,我准备将博客迁移到腾讯云服务器。使用国内的服务器最大的优点是,国内访问的速度非常快。但是,国内的服务器建站需要对域名备案,否则无法通过 HTTPS 访问网站。
迁移到腾讯云后,当博客有更行时,只能手动编译上传到服务器,这种方式非常麻烦,于是想到利用 GitHub Actions 自动部署博客,当更新博客时,由 GitHub Actions 编译同步到服务器。
启用 GitHub Actions
在开始前,先确保你本地已安装好 Hugo 博客系统。
首先,在博客源码的根目录创建一个 .github\workflows
目录,然后在此目录中创建一个 Actions 的配置文件,这里我命名为 deploy.yml
。文件的内容如下:
name: CodeClub Deloyment
on:
push:
branches: master
pull_request:
branches: master
jobs:
deployment:
runs-on: ubuntu-latest
environment:
name: Dev
url: https://${{ secrets.HOSTNAME }}
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Setting SSH key
uses: webfactory/ssh-agent@v0.5.4
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Scan public keys
run: ssh-keyscan ${{ secrets.HOSTNAME }} >> ~/.ssh/known_hosts
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
extended: true
- name: Build
run: hugo --gc --minify -b https://${{ secrets.HOSTNAME }}
- name: Deploy
run: rsync -avz --delete public/ ${{ secrets.USERNAME }}@${{ secrets.HOSTNAME }}:/var/www/html
name
: Workflow 的名称,这里可以按个人喜好定义。on
: 定义何时触发 Workflow,这里我定义当push
或PR
到仓库的master
分支,执行此 Workflow。jobs
: Jobs 是由一系列的steps
组成,这些steps
在同一个运行环境中按顺序运行。每一个step
要么执行一条 shell 命令,要么执行一个 Actions。
- uses: actions/checkout@v3
with:
submodules: 'recursive'
为了将源码部署到服务器上,第一步是从我们存储的仓库 checkout 出需要部署的网站源码。‘
- name: Setting SSH key
uses: webfactory/ssh-agent@v0.5.4
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
这一步是将我们的私钥添加到 Actions Runner 的 ssh-agent 中去。因为我们在使用 ssh 连接到服务器上时,需要使用密钥,但是每次运行 GitHub Actions 的主机是随机分配的,其公私钥并不是固定的。
- name: Scan public keys
run: ssh-keyscan ${{ secrets.HOSTNAME }} >> ~/.ssh/known_hosts
通常在使用 ssh 连接到一台新主机上时,会提示是否保存相应主机的指纹信息,自动化部署中,我们是无法响应此请求的,所以我们需要将需要连接的主机的公钥存储在 Actions Runner 的 known_hosts 中去,这里使用 ssh-keyscan 命令将要部署主机的公钥添加到 known_hosts 中。这样连接到服务器就不会提示保存主机指纹信息。
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
安装 Hugo 环境。
- name: Build
run: hugo --gc --minify -b https://${{ secrets.HOSTNAME }}
编译博客源码生成 HTML 文件。
- name: Deploy
run: rsync -avz --delete public/ ${{ secrets.USERNAME }}@${{ secrets.HOSTNAME }}:/var/www/html
使用 rsync
将编译的 HTML 文件同步到服务器的 /var/www/html
目录下。
设置 Secrets
在上面的 workflows 文件中,有几个 ${{}}
包裹的变量,这里是为了避免泄露隐私信息,例如私钥、登录用户名等新信息,因为 GitHub 公有仓库的文件任何人都可以查看。
这里使用 GitHub 提供的 Secrets 来隐藏隐私信息。在仓库的 Settings 中可以添加相应的值,运行时会替换 workflow 中的变量。
添加方法如下:在仓库的 Settings 页面选择 Secrets -> Actions,点击右上角的 New repository secret
添加 Repository secrets
。在 Environments -> {ENV_NAME},点击底部的 Add secret
添加 Environment secrets
。
注意:Secrets 根据作用域不同有两种,分别是
Repository secrets
和Environment secrets
。Repository secrets
在不同环境中都生效,Environment secrets
只在指定的环境中生效,使用Environment secrets
可以将不同分支的代码部署到不同的环境中。
遇到的问题
- GitHub Actions 部署时,因为 GitHub Actions 的服务器在境外,腾讯云会发送异地登录警告邮件,无法自动部署。需要在腾讯云主机安全控制台中为用于部署的用户创建白名单。