Hugo+Github Pages搭建静态网站作为个人博客(1)

温馨提醒

Hugo 是用 Go 实现的博客工具,采用 Markdown 进行文章编辑,自动生成静态站点文件,支持丰富的主题配置,也可以通过 js 嵌入像是评论系统等插件,高度定制化。除了 Hugo 外, 还有 Jekyll(github page默认)、Gatsby、Hexo、Ghost 等选择,实现和使用都差不多,可以根据自己的偏好进行选择。

安装 Hugo

在ubuntu24.04 LTS环境下到 Hugo Releases 下载对应的deb包(注意安装extend版本,许多第三方主题需要extend依赖),安装完成后,使用以下命令进行验证:

1
hugo version

创建 Hugo 网站

通过上述命令安装 hugo 程序后,就可以通过 hugo new site 命令进行网站创建、配置与本地调试了,如希望生成到 /path/to/site 路径:

1
$ hugo new site /path/to/site

这样就在 /path/to/site 目录里生成了初始站点,进去目录:

1
$ cd /path/to/site

站点目录结构:

1
2
3
4
5
6
7
8
9
.
├── archetypes: default.md是生成博文的模版
├── assets # 存放被 Hugo Pipes 处理的文件
├── content # 存放markdown文件作为博文内容
├── data # 存放 Hugo 处理的数据
├── layouts # 存放布局文件
├── static # 存放静态文件 图片 CSS JS文件
├── themes: 存放不同的主题
└── config.toml: 博客配置文件支持 JSON YAML TOML 三种格式配置文件

创建文章

创建一个 about 页面:

1
$ hugo new about.md

about.md 自动生成到了 content/about.md ,打开 about.md 看下:

1
2
3
4
5
6
7
8
+++
date = "2015-10-25T08:36:54-07:00"
draft = true
title = "about"

+++

正文内容

内容是 Markdown 格式的,+++ 之间的内容是 TOML 格式的,根据你的喜好,你可以换成 YAML 格式(使用 --- 标记)或者 JSON 格式。

创建第一篇文章,放到 content/post 目录,方便之后生成聚合页面。

1
$ hugo new post/first.md

打开编辑 content/post/first.md

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
---
date: "2015-10-25T08:36:54-07:00"
title: "first"
 
---

### Hello Hugo

 1. aaa
 1. bbb
 1. ccc

注意此项为可选步骤,跳过可直接copy他人主题

配置主题

当通过上文命令创建我们的站点后,需要进行主题配置,Hugo 社区有了很丰富的主题,可以通过官网 Themes 菜单选择自己喜欢的风格,查看预览效果,选择后可以进入主题项目的github仓库,一般人气多的主题都会有很详细的安装及配置说明。

传统方式使用的是将原主题仓库 fork 到自己的账户,并使用 git submodule 方式进行仓库链接,这样后续可以对主题的修改进行单独维护。

1
2
3
cd  cita-site/#进入网站工程根目录
git init
git submodule add https://github.com/CaiJimmy/hugo-theme-stack/ themes/hugo-theme-stack#笔者所用主题为stack,此行与你所选主题有关

然后在根目录下的 config.toml文件中添加新的一行:

1
theme = "your_theme"

此时大多数主题仓库提供example文件,你可以拷贝至你的工程根目录下,主要是content与config文件,之后就能进行下一步,如有问题建议查看主题提供的参考手册。

生成网页

为了查看生成的博客的效果,我们在本地编辑调试时可以通过 hugo server 命令进行本地实时调试预览,无须每次都重新生成。在bash中运行以下命令,即我们可以通过浏览器 http://localhost:1313/ 地址访问我们的本地预览网页。

1
hugo server

但此时只能在本地访问,如果想发布到 Github Pages , 还需要借助 GithubPages 工具。

Github Pages部署

假设你需要部署在 GitHub Pages 上,首先在GitHub上创建一个Repository,命名为:coderzh.github.io (coderzh替换为你的github用户名)。站点目录config.tomlbaseURL要换成自己建立的仓库,如baseURL = “https://cita-777.github.io/"

在站点根目录执行 Hugo 命令生成最终页面:

1
$ hugo --theme=hyde --baseURL="http://coderzh.github.io/"

如果一切顺利,所有静态页面都会生成到 public 目录,将pubilc目录里所有文件 push 到刚创建的Repository的 master 分支。

1
2
3
4
5
6
$ cd public
$ git init
$ git remote add origin https://github.com/coderzh/coderzh.github.io.git
$ git add -A
$ git commit -m "first commit"
$ git push -u origin master

浏览器里访问:http://coderzh.github.io/

注意必须只上传public中的所有文件,若无法使用密钥则使用ssh鉴定身份(git remote set-url origin git@github.com :cita-777/cita-777.github.io.git),目前github默认主分支为main,建议设置里改为master

后续修改网页

contentconfig进行自行随意修改后需要重新上传至github仓库同步更新。切记不要随意手动删除public文件让Hugo重新生成再尝试push,因为这会将public内的.git一起删除,你将需要重新配置git并且链接至远程仓库,当你使用hugo server命令在本地生存并预览网站后,Hugo会自动生成新的public文件,包含你对网站所作的所有新更改,而且你在static文件管理资源时所进行的增加与删除,public中只会进行增加而不会删除,本意是很好的,这是一种非破坏性修改。所以如果你有用不上的资源,记得在public文件内手动删除来减少空间占用,所以你只需要朴实无华的push即可,参考命令如下:

1
2
3
4
5
6
hugo server -D 
ctrl + c #关闭本地server
cd public #进入public文件内
git add -A #提交all变动
git commit -m "修改/更新了xxx" 
git push -u origin master #push到远程仓库

(进阶)Github Action 自动发布

通过前面的操作我们可以手动发布我们的静态文件,但还是有以下弊端:

  1. 发布步骤还是比较繁琐,本地调试后还需要切换到 public/ 目录进行上传
  2. 无法对博客 .md 源文件进行备份与版本管理

因此,我们需要简单顺滑的方式来进行博客发布,首先我们初始化博客源文件的仓库,如我的仓库为 pseudoyu/yu-blog

因为我们的博客基于 GitHub 与 GitHub Pages,可以通过官方提供的 GitHub Action 进行 CI 自动发布,下面我会进行详细讲解。GitHub Action 是一个持续集成和持续交付(CI/CD) 平台,可用于自动执行构建、测试和部署管道,目前已经有很多开发好的工作流,可以通过简单的配置即可直接使用。

配置在仓库目录 .github/workflows 下,以 .yml 为后缀。我的 GitHub Action 配置为 pseudoyu/yu-blog deploy.yml ,自动发布示例配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
name: deploy

on:
    push:
    workflow_dispatch:
    schedule:
        # Runs everyday at 8:00 AM
        - cron: "0 0 * * *"

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v2
              with:
                  submodules: true
                  fetch-depth: 0

            - name: Setup Hugo
              uses: peaceiris/actions-hugo@v2
              with:
                  hugo-version: "latest"

            - name: Build Web
              run: hugo

            - name: Deploy Web
              uses: peaceiris/actions-gh-pages@v3
              with:
                  PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
                  EXTERNAL_REPOSITORY: pseudoyu/pseudoyu.github.io
                  PUBLISH_BRANCH: master
                  PUBLISH_DIR: ./public
                  commit_message: ${{ github.event.head_commit.message }}

on 表示 GitHub Action 触发条件,我设置了 pushworkflow_dispatchschedule 三个条件:

  • push,当这个项目仓库发生推送动作后,执行 GitHub Action
  • workflow_dispatch,可以在 GitHub 项目仓库的 Action 工具栏进行手动调用
  • schedule,定时执行 GitHub Action,如我的设置为北京时间每天早上执行,主要是使用一些自动化统计 CI 来自动更新我博客的关于页面,如本周编码时间,影音记录等,如果你不需要定时功能,可以删除这个条件

jobs 表示 GitHub Action 中的任务,我们设置了一个 build 任务,runs-on 表示 GitHub Action 运行环境,我们选择了 ubuntu-latest。我们的 build 任务包含了 CheckoutSetup HugoBuild WebDeploy Web 四个主要步骤,其中 run 是执行的命令,uses 是 GitHub Action 中的一个插件,我们使用了 peaceiris/actions-hugo@v2peaceiris/actions-gh-pages@v3 这两个插件。其中 Checkout 步骤中 with 中配置 submodules 值为 true 可以同步博客源仓库的子模块,即我们的主题模块。

首先需要将上述 deploy.yml 中的 EXTERNAL_REPOSITORY 改为自己的 GitHub Pages 仓库,如我的设置为 pseudoyu/pseudoyu.github.io

因为我们需要从博客仓库推送到外部 GitHub Pages 仓库,需要特定权限,要在 GitHub 账户下 Setting - Developer setting - Personal access tokens 下创建一个 Token。