本文主要分享如何使用Hugo生成静态站点,并部署到firebase (Hosting服务)上。
updated: 2021/9/29
静态站点
静态站点,相比于动态站点(一般指需要请求后端动态生成网站内容)来说,网站内容已提前渲染好,对搜索引擎更加友好。而且网站内容一般可以直接生成静态的html/css页面, 减少浏览器js渲染,网络传输时也可以充分利用缓存, 这样网页加载也比较快, 使用户体验更好。
更进一步地,Google和Twitter合作开发了AMP(Accelerated Mobile Pages)技术, 通过限定HTML标签和CSS,以及CDN缓存,提升移动设备(相比于PC端:弱网、低性能)对网站的访问速度。
本站点就是采用了AMP技术构建, 使用静态站点生成工具根据模板,将markdown文件渲染输出为静态AMP页面。
生成工具
静态站点生成工具有很多,我主要用过的有以下两个。(目前又换回了Hugo)
PS, Hugo刚发布不久我就开始使用了,当时对这个新工具很喜欢,它是一个单独的二进制文件, 且渲染很快,模板丰富。但后面想定制一些功能(那时Hugo的文档比较少,仅官网使用文档, 且功能也没现在这么丰富), 但go的语法还是比较复杂的,也没太多时间看源码。因此当Scully出现的时候,我就立即使用了它(因为本人还是一个Angular粉),相比于Hugo,Scully几乎等同于你可以通过编写Angular应用定制你的网站, 因此十分灵活(主要的缺点是主题和应用代码分开进程渲染,调试略麻烦)。但后面发现,我本身写博客主题的时间可能比我写博客还花的多:》,也是该冷静下想想我的初衷是什么了。其实就是为了记录一些知识并分享,因此AMP才是我的需要。所以我决定我的博客主题的核心是简洁并对阅读友好, 而不是增添许多看其来很有趣的功能。
博客主题
这里列出我用过的博客主题
Hugo
Scully
以下内容主要介绍Hugo使用
安装和创建站点
目标
- 在本地电脑安装hugo, 在github上创建私有仓库
posts
,存放markdown源码及图片等文件; - 在github创建私有仓库
qtopie.web.app
(作为集成仓库), 对应于站点名称,存放站点配置文件。 - 创建firebase hosting项目,将站点
qtopie.web.app
发布到firebase.
仓库创建过程省略
Hugo安装
以在Ubuntu 20.04上为例
sudo snap install hugo
本地生成站点
初始化git各模块
// git clone ... ; cd <repo>
hugo new site .
git submodule add https://github.com/qtopierw/amp-blog-theme.git themes/amp-blog-theme
git submodule add git@github.com:<username>/posts.git content/posts
创建.gitignore
文件, 并加入public
目录
现在可以使用hugo
命令生成站点了(将输出到public
目录),或使用hugo server
命令进入开发模式
将应用发布到firebase
firebase工具安装
firbase是一个nodejs应用工具包,需要使用npm
或者yarn
安装
sudo yarn global add firebase-tools
发布
- 登录firebase账号
firebase login
# 如果需要使用代理
proxychains4 firebase login
- 初始化项目
firebase init
选择发布到firebase hosting和生成github CI (选择不覆盖public目录下的静态文件)
可以将github ci修改如下
.github/workflows/firebase-hosting-merge.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting on merge
'on':
push:
branches:
- main
# 新增部分
repository_dispatch:
types: sub_commit
jobs:
build_and_deploy:
runs-on: ubuntu-20.04
steps:
# 修改部分 - start
- uses: actions/checkout@v2
with:
submodules: recursive
token: ${{ secrets.PRIVATE_REPO_ACCESS_TOKEN }}
- name: PullLatestPosts
run: git submodule update --recursive --remote
- name: generate sites
run: sudo snap install hugo && hugo --minify
# 修改部分 - end
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_QTOPIE }}'
channelId: live
projectId: qtopie
使用firebase deploy
命令可以直接发布public
目录下的文件到github
使用github ci自动发布
当博客主题创建好后,实际上我们很少需要修改它,更多的时候我们是在改markdown文件,即提交代码到posts
仓库。
因此我们可以通过在posts
仓库创建github actions
,通过上面设置的sub_commit
触发器,让集成仓库拉取各分支最新代码,构建站点和发布.
posts
仓库 github actions配置如下
.github/workflows/trigger-events.yml
name: Dispatch Event
on: [push]
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: dispatch event to another repository
env:
GITHUB_TOKEN: ${{ secrets.PRIVATE_REPO_ACCESS_TOKEN }}
EVENT: sub_commit
ORG: qtopierw
REPO: qtopie.web.app
run: |
curl --fail -d "{\"event_type\": \"${EVENT}\"}" -H "Content-Type: application/json" -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" "https://api.github.com/repos/${ORG}/${REPO}/dispatches"
这里注意到,我们在两个仓库都使用了一个CI私有环境变量PRIVATE_REPO_ACCESS_TOKEN
,这个token我们可以在个人github settings页面生成, scope
选择repo
(全勾),然后将token复制后,在两个私有项目下分别创建一个Secret即可(名称PRIVATE_REPO_ACCESS_TOKEN
, 值为复制的token)
比如我的
posts
仓库设置secrets的链接为https://github.com/qtopierw/posts/settings/secrets/actions
设置完毕后,提交posts
仓库的更改就可以实现自动发布到站点了。
使用Azure Pipelines发布静态站点到GitHub Pages
这是旧的内容,可忽略
GitHub Pages is really a great place to host static site, and to make it easier to publish your blog, you may want to you some CI pipeline to autmoate this.
You may want to keep your blog source files private while release static files in github page. Fortunately, github has already provided free private git repos. But to enable github page on private repo you need to Upgrade to GitHub Pro or make this repository public to enable Pages.
, so for totally free hosting you have to create one public repo to host released static blog files.
And I just found Azure Pipelines provides 1 free CI job which can be used to automate publishing blogs, and here’s an good tutorial for Publishing GitHub Pages from Azure Pipelines
.
So now it becomes, what we’re going to need:
- Register to use Azure Pipelines
- One Github private repo to store blog source files and one public repo to host released github pages.
On you private repo, add azure pipeline configuration:
# Blog
# Build hugo blog in azure pipeline for private repo and publish it on public repo to use github pages
# https://cloudblogs.microsoft.com/opensource/2019/04/05/publishing-github-pages-from-azure-pipelines/
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
if \[ -f public \]; then rm -r public; fi
git clone https://your-repo.github.io.git public
git submodule init && git submodule update
displayName: 'Clone Github Pages'
- script: |
sudo snap install hugo
hugo
displayName: 'Generating docs'
- task: DownloadSecureFile@1
inputs:
secureFile: deploy_key
displayName: 'Get the deploy key'
- script: |
mkdir ~/.ssh && mv $DOWNLOADSECUREFILE_SECUREFILEPATH ~/.ssh/id_rsa
chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_rsa
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
displayName: 'Setup git deploy key'
- script: |
cd public
git config --local user.name "your-name"
git config --local user.email "you-email@users.noreply.github.com"
git add .
git commit -m "Publishing GitHub Pages ***NO_CI***"
git remote set-url --push origin git@your-repo.github.io.git
git push origin HEAD:master
displayName: 'Publish GitHub Pages'
condition: |
and(not(eq(variables['Build.Reason'], 'PullRequest')),
eq(variables['Build.SourceBranch'], 'refs/heads/master'))
Note that in my experience, every time use hugo
to generate sites, it will make file changes on public/en/sitemap.xml
,
so no need to worry about git commit
would fail.
On your public repo, add deployment key(recommend to use separate ssh key file on this repo for security reason, and write permission is needed). Then add the private ssh key named deploy_key
in azure pipelines -> Library -> secure file
.