迁移到 Hugo @ Amazon CloudFront & S3

迁移到 Hugo

我之前使用的是 Hexo，基本上和 Hugo 的使用方法差别不大，直接将文章复制过来就可以，检查一下文章的 Front Matter 部分即可。

检查完之后使用 hugo 命令生成网站静态文件备用，默认在 public 文件夹下。

配置 Amazon S3 Bucket

打开 AWS S3 控制台，新建一个 S3 Bucket。

进入刚刚新建的 Bucket 详细信息，打开静态网站托管功能，记录下「存储桶网站终端节点」备用。

去掉「权限」中的「阻止所有公开访问」，并将「存储桶策略」修改为下面的内容：

Copy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<bucket_name>/*"
}
]
}

将上一步得到的 public 文件夹下的所有文件上传到此 Bucket 中，访问刚刚的「存储桶网站终端节点」，可以看到页面即可（样式可能不正确）。

配置 Amazon CloudFront CDN

打开 AWS CloudFront 控制台，新建一个 Web 分配，先找到「SSL 证书」，点击「使用 ACM 请求或导入证书」，先给域名申请一个证书，然后刷新创建分配页面。

按照下面的说明设置参数，其他保持默认即可：

源域名：选择刚刚建立的 Bucket

查看器协议策略：将 HTTP 重定向到 HTTPS

SSL 证书：选择「自定义 SSL 证书」，下面列别中选择刚刚申请的证书

创建好后点击刚刚创建的分配 ID，点击「源和源组」，编辑「源」，将源域名更改为「存储桶网站终端节点」，保存。

这时候使用域名访问，应该可以正常看到页面。

配置 GitHub Actions 实现自动部署

前阵子为了实现自动部署，专门写了个 Deployer，这次迁移不能降级体验。

因为不再部署在自己服务器上，再用 Deployer 有点多余，于是就选了 GitHub Actions。

下面是 GitHub Actions 的 Workflow 文件：

Copy
name: Deploy to Amazon S3

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
with:
submodules: true
fetch-depth: 0

- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.80.0'

- name: Build
run: hugo --minify

- name: Deploy to S3
run: hugo deploy --force --maxDeletes -1 --invalidateCDN
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

注：使用前需要在项目的 Secrets 中添加 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 两个环境变量。

修复 index.xml 文件的元数据

Hugo 默认的 Deploy 功能会把 xml 文件的 Content-Type 设置为 application/rss+xml，实测访问会乱码，改为 application/xml 或 text/xml 即可解决。

可以在 GitHub Actions 的 Workflow 中加入下面内容，这样就不用每次手动修改了：

Copy
...
jobs:
deploy:
...
steps:
...

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: Fix Content-Type for index.xml
run: |
aws s3api copy-object --bucket "$AWS_BUCKET" --content-encoding "gzip" --content-type "text/xml" --copy-source "$AWS_BUCKET/index.xml" --key "index.xml" --metadata-directive "REPLACE"
env:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
AWS_BUCKET: ${{ secrets.AWS_BUCKET }}

注：需要在项目的 Secrets 中另外添加 AWS_REGION 和 AWS_BUCKET 两个环境变量。

完整的 Workflow 文件

Copy
name: Deploy to Amazon S3

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
with:
submodules: true
fetch-depth: 0

- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.80.0'

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: Build
run: hugo --minify

- name: Deploy to S3
run: hugo deploy --force --maxDeletes -1 --invalidateCDN
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

- name: Fix Content-Type for index.xml
run: |
aws s3api copy-object --bucket "$AWS_BUCKET" --content-encoding "gzip" --content-type "text/xml" --copy-source "$AWS_BUCKET/index.xml" --key "index.xml" --metadata-directive "REPLACE"
env:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
AWS_BUCKET: ${{ secrets.AWS_BUCKET }}

需要配置的 Secrets：

AWS_ACCESS_KEY_ID

AWS_SECRET_ACCESS_KEY

AWS_REGION

AWS_BUCKET

参考

如何为静态网站托管配置 S3 存储桶？

使用 Amazon S3、Cloudfront 部署靜態網站

Using GitHub Actions and Hugo Deploy to Deploy a Static Site to AWS

"Configure AWS Credentials" Action For GitHub Actions

copy-object

How to change content type of Amazon S3 Objects