玩转Github Pages

Github Pages是 Github 的一个免费静态网页托管服务。可以用来做个人博客，项目简介 / 文档，组织官网（如实验室官网）等。本文将详细介绍 Github Pages 的使用方法（其实步骤非常简单，最快 10 分钟就可以起一个网站）。开始前先进一段简介，也可以直接跳到做项目主页和个人博客的具体步骤。

Pages 简介

Pages 的优点是不需要配服务器，数据库这些环境，简单，稳定，免费。这使得 Pages 很适合做个人博客，项目主页，企业官网这一类纯展示性质（可能也不产生收益 😂）的站点。其缺点是只能托管静态网页，意思是对于每个访问者网站展示的内容都是一样的。这不意味着 Pages 里不能有任何动态的元素，比如可以结合 Issue 或 Discussion 实现博客评论。但是要做功能复杂的网站（比如带登录的）或者有复杂的数据处理，大概还是有一个服务器后台会更方便。

Pages 在项目每次更新后会做两件事：

将项目中的 Markdown 用 Jekyll 转成网站

托管这个网站

因为 Jekyll 只会根据一些配置文件处理 Markdown 文件，所有的网页都会原样保留，所以也可以直接往项目中推构建好的网站，只是白嫖一下托管。这种方案可以用任何方式，比如hexo和hugo，过程和用 Jekyll 本地构建后直接上传网站相同。

总结起来用 Pages 主要有三种姿势

上传 Markdown，直接让 Pages 用 Jekyll 构建成网站托管

上传 Markdown，用 Github Action 构建成网站托管

直接上传网页，让 Pages 托管

这三种方法操作复杂度和灵活性都是依次递增。

第一种方式最简单也很方便，但是 Pages 的 Jekyll 只提供了13 个为项目主页设计的单页主题，所以通常也只有项目主页用第一种方式。

个人博客和组织官网用第二种的居多，直接 Fork 一个主题项目就行，够灵活而且不用本地配环境，Action 的构建脚本通常 Jekyll 主题都自带，不需要操心自己写。

直接上传网页灵活性最高，不过大多数场景下感觉没有必要。除非是没用 Jekyll 这种工具生成网页，而是自己直接写的网页，否则感觉第二种方法就够用了。

Github

这段面向之前完全没用过 Github 和 git 版本管理工具的读者，简单说说如何注册 Github，创建项目和 git 是什么。

Github 是一个代码托管平台，开发者把代码上传到这个平台上，方便一个项目的多个开发者同步代码，同时也有助于开源项目的传播。注册需要一个邮箱，访问Github 注册页面，按提示操作就行。

Github 上的项目可以自己新建也可以复制别人的，就做博客来说直接复制主题项目比较多。Fork 的意思就是将别人的一个项目复制一份，存到自己的 Github 账户下。在每个项目的右上角都有一个 Fork 按钮

点击之后就会跳转到一个自己的新项目，项目的内容和名称都和原来的项目一样。这个项目已经在自己的账户下，可以进行修改。

如果是要创建自己的项目，点主页左边一个绿色的创建新项目（New）按钮就行。

一般建议添加一个 README.md，空项目是没法直接从 Github 往下拉的，需要本地跑几行操作，稍微麻烦一点。

git 是一个代码版本管理工具，简单来说可以让你在写代码过程中创建一些存档点。如果只有一个开发者那么这些存档点大概就是一条直线，一个比一个新，像下面图里的红线。如果有多个开发者同时对项目做修改，存档点可以有一些平行的路径，像下面图里的蓝线和黄线。就做个人博客来说不需要了解很多的 git 知识，操作也不需要命令行，有很多带界面的 git 软件比如Github Desktop和gitg。做博客最简单的方法是 Fork 一个主题项目，将项目 pull 到本地，进行修改，之后再将修改 push 到 Github 上。后面用到的时候回说具体怎么操作。

项目主页

从最简单的开始，先介绍怎么做项目主页，也就是怎么用 Pages 直接把 Markdown 变成一个能访问的网站。首先打开一个 Github 项目，点进 Settings->Pages 页面。一个没开启 Pages 的项目应该是这样的

Source 这里选 Markdown 所在的 Branch

后面的文件夹选项是指定在这个 Branch 下去哪找 Markdown 文件。如果只在根目录下有一个 README.md 的话保持默认 /(root) 就行，如果文档是分成多个文件可以都放到 docs 文件夹下，选择 /docs。

保存。

稍等一会访问上面这个网址就能看到网页了。Pages 用一个 Enviroment 进行静态网站生成和托管，查看进展的方法是首先回到项目主页

在右下角可以看到一个 Enviroments，点进那个 github-pages

就可以看到部署的执行情况，刷新几次就会看到一条新的部署记录，点 view deployment 就会跳转到网页了。

默认部署没有主题看起来大概比较素，可以在 Settings -> Pages -> Theme Chooser -> Choose a theme 这里选一个主题。

点击之后会看到主题的预览，点 Select Theme 选中一个主题。

这个时候 Pages 会在代码里创建一个_config.yml 文件，记下你选的主题。内容类似这个

等一会 Pages 更新之后就能看到带主题的网页了。

Pages 给了 13 个主题，做项目主页的话不建议用这 13 个之外的。Pages 的文档中描述了怎么使用外部主题但是 Pages 的 Jekyll 环境比较简单，很多主题都会缺 gem 依赖，而且部署过程貌似也没有详细的 log，出问题了大都跟下面一样只有一句构建失败，不太好 debug。

想用第三方主题建议用 Action 创建一个环境编译。

个人博客

下面就到了这篇的重头戏，用 Pages 部署个人博客。过程非常简单，选一个主题，用 Jekyll 或者类似工具（如hexo，Octpress）把 Markdown 构建成 html，之后推到 Github 项目中就完成了（个人只用过 Jekyll 所以下文也是针对 Jekyll 写的，但用其他工具的流程也是一样的）。构建的这一步通常用 Github Action，非常方便，搭建的过程 10 分钟就能搞定。本地构建麻烦一些，但是灵活度高，下文将分别介绍。

主题

如果是前端大佬大可以用 html，css，js，liquid 这些语言自己搞一个主题，不过 Jekyll 有很丰富的主题生态可以即 Fork 即用。选择主题的指导原则是好看和好用。好看纯看个人审美，没什么好说的。好用是希望主题的功能尽可能丰富。一些常见的功能包括：

博客内搜索

自动生成 sitemap：便于搜索引擎收录，搜索引擎大概会是博客最主要的流量来源

文章标签和分类：博客首页一般都按发表顺序展示文章，内容多了之后标签和分类会比较实用

文章目录 TOC：长文用的上

发表时间，修改时间：发表时间一般都是有的，修改时间要看 git 记录，不是所有主题都有

深色模式

代码块

数学公式

...

这些功能主题就算没有也都可以自己加，不过主题带的话可以省很多麻烦。主题一般都是 Github 项目，质量高的通常 Star 和 Fork 数比较多，更新频率高。好的主题一般教程详细，部署过程中也不容易出问题。

本文以我正用的Chirpy为例，更多的主题可以逛逛下面这些网站

Github 上的 #jekyll-theme

jamstackthemes.dev

jekyllthemes.org

jekyllthemes.io

jekyll-themes.com

推荐 Fork 主题，优点是用 Github 最近出的 Fetch Upstream 跟着上游更新主题比较方便。

Fork 项目之后需要按照 用户名.github.io 格式改项目名，比如我 Github 用户名是 linhandev，那项目名就是 linhandev.github.io。点 Settings 第一个设置就是。

如果名字冲突要删之前的博客千万千万记得保存内容，之前丢过好几波写好的文章。。。占名字的项目也不需要删，改个名字就行。

看一看主题的 README 对使用方法的介绍，一般都会仔细的写 Fork 之后需要进行哪些操作，比如 Chirpy 会需要运行一个脚本。看文档虽然无聊，但绝对比出问题之后一通 debug 节省时间。谋定而后动，最近面试感觉自己这方面差很多。

Jekyll 的主要设置都在根目录下的 _config.yml 文件里，比如网站标题 title ，副标题 tagline，时区 timezone，头图 avatar，和一些社交媒体配置之类的。走一波这个文件，一般都有注释每个设置是啥，把想改的改一改。

Action 构建

Action 写起来稍微复杂，不过大多数主题要么自带用 Action 构建的脚本，要么可以直接用 Pages 的环境构建。写这部分的目的主要在于方便在博客构建失败的时候 Debug，以后可能会更新这个 Action 具体怎么写。如果主题没提供这个脚本，自己对 Action 也不熟悉的话，那本地构建会更简单。

Github Action 会在项目有一些动作之后触发，比如 push，开 Issue 之类。Action 的配置在项目的 .github/workflows 文件夹下。首先一定看一下主题 README.md 里有关开始使用的部分，一些主题会有一个初始化的脚本，之前用 Chirpy 的时候就因为没仔细看文档走了一堆弯路。

每次 push 更新之后 Action 会自动执行，在项目的代码页面 commit 的左边会有一个图标，就是下图红框的位置

Action 执行过程中是一个黄点，执行成功是一个绿色的对号，如果看到一个红叉就是执行出问题了。执行成功之后点代码左上角的下拉菜单看看是不是多出一个 branch

修改 Settings->Pages 里的设置，将 Source 改成这个 branch

如果 commit 左边图表是红叉可以看一下 Action 执行的 log 来排查具体是什么问题。

点项目上面的 Action 能看到所有的执行

点进其中的一次执行是这样

点在那个 continus-delivery 位置的按钮（不一定叫一个名字）可以看到具体的执行 log。

展开出错的部分就可以看到具体是什么问题了。

第一次执行 Action 需要创建环境，下一堆依赖应该会比较慢，可能要几分钟。Chirpy 的 Action 脚本会缓存 Ruby 的环境，以后每次执行大概只需要半分钟。Action 执行成功后 Pages 还需要几分钟才会更新，只要 Action 执行成功了这次发布就没什么问题，等着就行。

本地构建

使用 Action 构建很方便，主要的缺点是每次 push 之后需要等上几分钟才能看到效果。一般这没什么，但如果遇到一些问题需要反复编译去 debug 的时候也会让你一通好等。本地跑 Jekyll 可以实时编译，保存之后刷新网页就能看到更新。

安装环境

Jekyll 用 Ruby 编写，本地运行需要装 Ruby 和 Ruby 的包管理工具 RubyGem，这里列一下 Arch Linux 的安装步骤，其他系统可以参考官方安装文档

Copy
sudo pacman -S Ruby base-devel

安装的过程中遇到个小问题，pacman 下清华源几个文件一直失败。解决的方法是上清华源的网站，直接下载对应的安装包文件之后 pacmsn -U 安装。装好 Ruby 之后换源，之后装 jekyll，bundle

Copy
# 添加清华源并移除默认源
gem sources --add https://mirrors.tuna.tsinghua.edu.cn/Rubygems/ --remove https://Rubygems.org/
gem sources -l # 列出所有源，应该只有TUNA一个
gem install jekyll bundler # 装包
bundle # 让bundle安装jekyll的依赖
jekyll # 测试安装是否正确
# 头两行输出应该是
# A subcommand is required.
# jekyll 4.2.1 -- Jekyll is a blog-aware, static site generator in Ruby

如果上面最后一行输出的是找不到 jekyll 命令，那应该是可执行文件路径里没有 gem 中的 bin 文件夹，仔细看看gem install命令的输出应该针对这个问题有提示，把 bin 的路径添加到 PATH 里就行。

Copy
gem environment # 找输出里的 GEM PATHS 部分
export PATH=$PATH:[上面的gem path] # 比如Arch上是 /usr/lib/Ruby/gems/3.0.0
jekyll # 试试改的对不对
# 如果能找到命令了就把这行写到 ~/.bashrc 里，这样打开一个新命令行依旧有效
echo 'export $PATH=$PATH:[上面的gem path]' >> ~/.bashrc # 必需单引号，双引号会用值替代变量

到这 Jekyll 的环境应该就配置好了，下一步进行构建和 push。

构建和 push

首先把 Github 上的项目 clone 到本地，创建新项目或者 Fork 主题，项目名要求是 Github 用户名.github.io 这些前面已经说过了。如果创建新项目添加一个空的 Readme 方便后面 clone。完成后把项目 clone 到本地。

Copy
git clone https://github.com/[username]/[username].github.io
cd [username].github.io # 进到项目里

如果是新项目将主题的所有文件放到项目里。应该有_config.yml，index.html，_post 之类的一堆文件和文件夹。

这个时候就可以本地构建了

Copy
jekyll build # 构建结果在_site文件夹里
# 或者
jekyl b # b是简写，效果是一样的

此外还可以起一个本地的服务展示博客，每次 Markdown 文件保存后网站都会自动重新构建，刷新页面就能看到修改

Copy
jekyll serve # 之后访问 Server address: 那个网址就能看到
# 或者
jekyll s # 简写

构建成功之后给构建出来的网页文件单独创建一个 branch。下面的脚本有删除的代码，一定确定好自己在哪个 branch 上，否则可能误删 Markdown 文件。

Copy
git branch # 查看一下当前分支叫什么，一会还要回来
git branch gh-page # 创建 gh-page branch
git switch gh-page # 切换到新branch
git rm -r * # checkout会把原来分支的所有文件都带过来，删掉它们
git commit -m "clean up"
git push --set-upstream origin gh-page # 推到 Github上
git checkout main # 返回之前的branch

分支创建完成了，build 并推到 Github 上。

Copy
# 在主分支构建
git switch main
jekyll build # md转html

# 将 _site 中生成的html网站放到 gh-page 分支的根目录里
git switch gh-page
mv _site .site
rm -rf *
mv .site/* .
rm -rf .site
ls # 应该有404.html，main.html这样的文件

# 在 gh-page 分支 push
git add *
git commit -m "Update Blog"
git push

# 返回 main 分支 push
git switch main
rm -rf _site
git add *
git commit -m "Update Jekyll Blog"
git push

到这复杂的部分基本就完成了，最后跟前面一样改一下 Pages 的 Source。到 Github 项目的 Settings->Pages 里，将 Source 设成 gh-page，/root，保存。

等几分钟网站应该就可以访问了。

博客评论

你可能希望大家在看完博客之后给点反馈。文章评论不是一个静态的功能所以光靠 Github Pages 实现不了。我了解到的方案主要是两类

用自己搭建的或第三方的评论服务

用基于 Github Issue 或 Discussion 的方案

最开始我是用的第三方评论服务hyvor，当时试运营是免费的但是现在已经收费了。这种服务套餐的量一般都很大，比如 hyvor 起步的 $5 / 月套餐就有 10w page view。估计我有生之年博客都不会有这么大的流量。😂

Github 的服务依旧更加良心。😂 这一类的项目有很多，一些主题可能对其中的一些有内置的支持，比如 Chirpy 就内置了对 disqus，utterances（基于 Issue）和 giscus（基于 Discussion）的支持。这类方案的主要的缺点是貌似所有的项目都需要用户 Github 登录之后才能评论，一些还会需要用户 OAuth 授权。

utteranc

gitalk

gitment

vssue

目前用的是 utteranc，就以它为例，其他的也都差不太多。

utteranc 会给每篇文章创建一个 Issue，用户对文章的评论会保存为 Issue 下的回复。评论的时候会需要用户用 Github 账户登陆，之后授权 utteranc。

安装过程很简单

访问这个网址，在 Gtihub 上安装 utterances app

可以只给博客一个项目的权限

安装完成后会打开utteranc 网站，按照引导进行设置，先写项目名

选择每篇文章 Issue 的格式

这里要注意 utteranc 会按照配置的格式去找文章对应的 Issue，基本上是根据文章的标题或者 Markdown 文件名。如果修改了文章的标题或者 md 文件名也需要修改对应 Issue 的名字，否则就找不到任何评论。个人感觉设第一个是最好的，文件名估计不会有文章名改的多。

之后可以填一个 utteranc 创建 Issue 的标签，作用不大

最后选择一个和主题视觉协调的配色

下面能看到一段代码，把它插入到文章模板里正文下面的位置就可以用了。Chirpy 的文章模板是在 _layouts/post.html，别的主题也都类似。最后的效果

本地编辑环境

Markdown 不是所见即所得，而且插入图片一般有点费劲。本地环境可以很好的解决这些问题，简化写作流程。个人很喜欢 Atom，在另一篇文章中记了如何配置 Atom 写 Markdown，可以参考。

搜索引擎收录

一般个人博客的流量都不大，Chirpy 主题的作者甚至不推荐大家开文章浏览量功能，怕打击博主的创作热情 😂 不过如果你的博客有一些高质量的内容，搜索引擎是可以带来一些流量的。

搜索引擎优化是一门学问，但如果只是很佛系的告诉搜索引擎：“我有个网站，你爬不爬看着办”，那只要添加 robots.txt，之后提交一个 sitemap 就行。

sitemap 可以看作网站的地图，告诉爬虫我这个网站都有些什么页面可以访问。大多数主题都会带这个功能，访问 [github id].github.io/sitemap.xml ，如果不是 404 那就是有 sitemap 的。比如我的长这样

如果你的主题不带 sitemap 也可以自己添加

robots.txt 是用来告诉搜索引擎网站上哪些网页该爬，哪些网页不该爬的。可以访问 [github id].github.io/robots.txt 看看自己有没有这个文件。如果没有的话，在项目根目录中加上一个 robots.txt 文件就行，一个最简单的写法是

Copy
User-agent: *

Disallow: /norobots/

Sitemap: https://[github id].github.io/sitemap.xml

{: file='robots.txt'}

这个文件告诉搜索引擎所有类型的爬虫都可以爬这个网站，除了 /norobots/ 路径下的所有页面都可以爬取和网站的 sitemap 在哪。

robots.txt 和 sitemap 俱全就可以向搜索引擎提交网站了。这里需要用到各大搜索引擎的站长工具，webmaster 或者 search console。下面是一些常用的搜索引擎站长工具链接。

百度

Bing

Google

搜狗

头条

神马

360

提交的过程类似：

注册帐号

证明网站是你的

提交 sitemap

证明这一步通常有多种方法，对于 Pages 来说最方便的应该是添加文件。只需要将文件下载下来扔到项目根目录下，之后把修改推上 Github 就行。注意这个文件要放在构建前的有 Markdown 目录而不是构建出来的网页目录，否则重新构建会把这个文件抹掉。

第二种常用的方法是在网站 header 中加入 meta tag，这种方法的优点是添加多个搜索引擎的话项目的根目录整洁一些（如果这可以算优点的话）。tag 的内容是一串随机字符。比如我的 bing 搜索验证 tag 是

Copy


在 Chirpy 主题中网站的 header 部分在 _includes/head.html 定义，如果你的主题目录结构不一样可以在项目里搜一下 head 开头的文件。找到之后这行代码放到 head.html 的 head 部分就行了。

验证身份后找带 sitemap 的 tab，点进去输入 sitemap 网址就大功告成了。就我这个网站添加多个搜索引擎之后不多的流量来看，bing 国内版似乎是对新网站最友好的，大概提交 sitemap 3 4 天之后就能看到来自 cn.bing.com 的流量。Google 也有一两个，其他国内的搜索引擎大多数连爬都懒得爬。

流量统计

换位思考，我不想被别人统计所以也不做流量统计。

自定义域名

Pages 的默认网址是固定的，比如个人博客都是 用户名.github.io，项目网站都是 用户名.github.io/ 项目名 。但是 Pages 也支持自定义域名。

要用自定义域名非常明显首先要自己有一个域名，这个在各大云厂商都能买到，大概的过程是

到百度，阿里，腾讯这样的云服务上注册一个帐号

实名认证

找到域名产品

选一个下单

就可以了。价格跟很多因素有关，比如域名长度，顶级域名是什么，买多久之类的，大概每年几十。如果不想花钱也可以到Freenom申一个免费的。

在域名解析的后台将这个域名 CNAME 解析到 用户名.github.io，之后在项目的 Settings -> Pages 里面填写自己的域名。这个时候 gh-page branch 里会多一个 CNAME 文件，本地注意 pull 一下否则会冲突。在 main 分支的根目录里也加入这个文件。之后就可以使用自己的域名访问了。

之前从自定义域名转换回 Github 给的免费域名过程中遇到一点麻烦，输入免费域名总是直接跳转到之前解析的自己的域名，之后页面显示 Github 的 404。这种情况清一下浏览器的 cache 就好了。

结语

到这基本上 Github Pages 的基本用法就介绍完了。这篇文章还会不断更新进行更正和丰富。如果使用过程中有任何问题也欢迎在下方评论留言。