GitHub Pages 與 GitLab Pages 架設 Blog

筆者最近把個人 blog 的產生工具從 GitHub Pages 預設的 Jekyll 換成 Hexo,有了一點心得。 而且不只 GitHub Pages, 筆者在公司業務中也有大量使用 GitLab Pages 來產生文件及測試報表,算是有累積不少經驗。

趁著印象還深刻時,寫點筆記,替這兩個相同性質的服務做基本的介紹。

Pages 服務與 Static Site Generator

GitHub / GitLab Pages 可以將一組靜態網頁內容 (html, css, js 等),透過 GitHub / GitLab 的伺服器,host 在某個 URL 底下。 網頁產生工具 (Static Site Generator, 下稱 SSG) 則是 一個可以將用 Markdown 撰寫的文章,轉化成漂亮的靜態網頁內容的工具。常見的 SSG 有 Jekyll(Ruby), Hugo(Go), Hexo(JavaScript) 等。

若將 SSG 工具與 GitHub / GitLab Pages 服務,搭配使用, 寫作者只需要寫寫簡單的 Markdown 並 push commit,就能得到一個漂亮的 blog 或是文件網頁。 筆者的個人 blog 及公司的工作筆記即是使用這類流程架設。

整體流程大概如下圖所示:

1
2
3
4
5
6
7
8
9
               +   GitHub            +     github.io
Local Project | Project | site
| GitLab | gitlab.io
+ +

+----------+ +----------+ Build & +------+ User
| Markup | Push | Markup | Deploy | Site | Browse
| config.. | +----> | Config.. | +-------> | | +------->
+----------+ +----------+ +------+

GitHub Pages

GitHub Pages 基本上會有兩種主要的使用方式。 可以直接使用 GitHub Pages,或是透過 GitHub Pages 的 Jekyll 整合功能。 前者需要的技術背景與設定步驟均較複雜,後者較簡單但缺少了根據個別需求調整的機會。

Native GitHub Pages

若直接使用 GitHub Pages,使用方式是: 將 SSG 產生的網頁擺放至某 branch (預設為 gh-pages) 的 //docs 目錄。 每次該 branch 被更新時,GitHub 就會將最新版本的網頁內容, 呈現在 https://<username>.github.io/<project> 連結下。

早期這個 push brach 的動作是蠻麻煩的,但後來有了 GitHub Action 之後, 產生網站和後 push branch 的動作都可以在 GitHub 提供的環境完成,非常方便。

筆者個人使用的 job 描述檔如下:

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
# .github/workflows/blog.yaml

name: build-and-deploy-blog

on:
push:
branches: [ "master" ]
pull_request:

jobs:
blog:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2.3.4
- name: Setup Node.js environment
uses: actions/setup-node@v2.1.5
with:
node-version: 12.x
- name: Install dependent packages
run: npm install
- name: Build blog posts
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public

若不想使用 GitHub 提供的 domain,也可以參照 官方文件, 使用自己購買的 domain 來架設網站。 只要設定完成,GitHub 也可以一併幫使用者申請 custom domain 需要的 HTTPS 憑證。

比方說筆者的 blog 原本可存取的位置應是 https://wdhongtw.github.io/blog,但有設定 custom domain 後,目前是透過 https://blog.bitisle.net 來存取架在 GitHub Pages 上的 blog。

GitHub Pages Jekyll

前述 (Native) GitHub Pages 的使用方式會需要自己 push branch。 但若 GitHub 偵測到 project 使用的 SSG 是 Jekyll,GitHub 會自動處理產生網頁以及 後續部屬到 https://<username>.github.io/<project> 的工作。 (連 gh-pages branch 都省了,整個 project 會非常乾淨。)

此方法相當容易上手,也是 GitHub Pages 教學文件預設的使用方式。但因為產生網站的 環境是由 GitHub 協助處理,能使用的 Jekyll plugin 自然也是受到限制。

說是受到限制,但以一般使用情境應該也很夠了。諸如 RSS feed, sitemap, Open Graph metadata 等現代 blog 必備的功能都有自帶。 若想知道有那些 Jekyll plugin 可用,可至 Dependency versions | GitHub Pages 查閱。

Compare Native GitHub Page with GitHub Pages and Jekyll

簡單比較上述兩種方式如下

GitHub Page GitHub Page with Jekyll
SSG Tool on your choice only Jekyll
Deployment push generated site done by GitHub
Customization any plugins of SSG limited Jekyll plugin list

GitLab Pages

GitLab Pages 與 GitHub Pages 一樣,有將 SSG 產生的網頁 host 在特定網址的能力。 以 GitLab 官方 host 的站台來說,網站會放在 https://<username>.gitlab.io/<project> 下。 (私人或公司 host 的 GitLab instance 就要看各自的設定)

與 GitHub 不同的是,GitLab Pages 並不是透過 push branch 的方式部屬, 且沒有針對特定 SSG 提供更進一步的自動部屬功能。

GitLab Pages 的使用方式是基於 GitLab CI Pipeline 的架構設計的。若想要部屬 網站,一般的使用方式是在 pipeline 內產生網頁,接著將網頁內容擺放至為特定 job (pages) 的特定 artifacts 目錄 (public) 中。 一旦有 pipeline jobs 達成此條件。 GitLab 就會 把網頁內容部屬到對應的網址下。

筆者個人使用的 job 描述檔如下: (因為 GitHub Action 與 GitLab CI 的架構差異,寫起來比較簡潔)

1
2
3
4
5
6
7
8
9
10
11
12
13
# .gitlab-ci.yml
pages:
image: ruby:3.0.1
stage: deploy
before_script:
- bundle install
script:
- bundle exec jekyll build --destination public --baseurl "$CI_PAGES_URL"
artifacts:
paths:
- public
only:
- master

至於其他 GitHub Pages 有的功能,如 custom domain,自動申請 HTTPS 憑證等,GitLab Pages 也都有。 記得去 project 設定頁面設定即可。

Conclusion

在 2008 年 GitHub Pages 剛推出時,使用者都要自己手動 push gh-pages branch。 後來 GitLab 推出基於 GitLab CI 的 Pages 服務之後,GitHub Pages 使用體驗相較之下可說是非常糟糕。

但後來隨著 GitHub Actions 服務推出,以及社群維護的高品質 Pages 部屬 Action 出現。 GitHub / GitLab Pages 的使用體驗已經變得相當接近。 其他像是 custom domain 以及 HTTPS 的支援也都是免費的基本功能。

基於上述原因,許多早期的 比較文章 其實已經沒什麼參考價值。 若現在想架設新的 blog 等站台,只要選擇自己習慣的平台即可。

References

利用 GitHub Page 經營 Blog

如果要用一句話來簡單說明 GitHub Page,那基本上就是

指定一個 Git 版本庫來作為存放網站資源的地方,然後讓 GitHub 幫你把網站架起來。

任何人只要申請一個 GitHub 帳號,都可以免費的享有這個服務。

當然,考量到 GitHub 只是把我們放在版本庫上的檔案,讓別人透過瀏覽器瀏覽, 那種需要用到資料庫的可互動網站基本上是很難達成。 但若我們只是要經營一個部落格,或是存放專案文件等靜態網站時,GitHub Page 就會是個很合適且方便的選擇。

本文會粗淺的介紹如何利用 GitHub Page 來經營自己的 Blog, 以省去自行架設機器的各種煩惱。 :D

GitHub Page 的類別

目前 GitHub Page 有兩類的站台,一類是 User Page、另一類是 Project Page。 (其實還有 Organization Page,但這邊就不花時間贅述) User Page 與 Project Page 最主要的差別在於專案名稱的限制,與網站的 URL 格式這兩點。簡單整理如下

User Page 特點:

  • 專案名稱須為 <username>.github.io,其中 <username> 即為 GitHub 帳號的使用者名稱。
  • 站台會擺在 http(s)://<username>.github.io 供他人瀏覽

Project Page 特點:

  • 專案名稱沒有限制。 若假設專案名稱為 <projectname>
  • 站台會擺在 http(s)://<username>.github.io/<projectname> 供他人瀏覽

因為專案名稱的限制,一個 GitHub 帳號只能有一個 User Page 但可以有多個 Project Page。

更詳細的介紹請參考 官方網站的說明

GitHub Page 使用方式

GitHub Page 的使用方式也可以簡單分成兩種。

第一種是直接建置好的整個網站直接 push 到 GitHub 上,供使用者瀏覽。 若我們需要架一個 Blog,可以先用 Markdown 等 markup language 撰寫文章, 之後利用 Jekyll(Ruby)、Hugo(Golang) 或 Hexo(JS) 等靜態網站生成工具, 建出一個 Blog 網站並 push 上去。 又或我們需要 host 一個專案文件站台時,可以將 Doxygen 或 Sphinx 等工具 產生出的網站推上 GitHub。

1
2
3
4
5
6
7
8
                                    +
Local Project | GitHub Project
| github.io site
+
+----------+ +--------+ +------+ User
| Markup | Build | Site | Push | Site | Browse
| config.. | +------> | | +-----> | | +------->
+----------+ +--------+ +------+

如果我們是使用 Jekyll 來建置我們的網站,那 GitHub Page 有提供我們第二種用法。 我們可以將 Markup 和其他 Jekyll 需要的設定檔 push 上 GitHub,讓 GitHub 幫我們 建置網站,並在 github.io 網域上放出網站供人瀏覽。

1
2
3
4
5
6
7
8
               +                    +
Local Project | GitHub Project | github.io site
| |
+ +
+----------+ +----------+ +------+ User
| Markup | Push | Markup | Build | Site | Browse
| config.. | +----> | Config.. | +-----> | | +------->
+----------+ +----------+ +------+

第二個做法的缺點是,GitHub 只支援 Jekyll 這套工具,其他同性質的工具的不支援。 但相對來說也有優點,即是我們不須把工具建出的網站內的所有檔案都進到 commit 中。 (在 git project 中看到許多無意義 diff 實在不是工程師所樂見的事情 XD)

針對這兩個方式的更詳細說明,也請見官方文件

簡單的流程說明

接下來會介紹使用 Jekyll,並讓 GitHub 幫忙 build 與 host 網站的簡單步驟。

參照 官方介紹 的說明,最簡單的方式,其實只需要 我們點開 project 的 GitHub 設定頁面,找到 GitHub Page 的設定選項,設定一個 Jekyll 使用的主題,並用 Markdown 寫一個首頁文章即可。

用此方法會在專案內產生首頁的 index.md 檔案及一個 Jekyll 的設定檔 _config.yml。 檔案內僅一行你選的主題名稱

1
theme: jekyll-theme-minimal

但基本上,一個 完整的 Jekyll 專案 不會只有這兩個檔案,到最後我們還是得把其他需要的檔案生出來。 所以個人推薦使用下述方法建立我們的專案。

(假設我們已經裝好 Git 和 Jekyll 等工具。)

建立 Git 專案

1
2
mkdir website && cd website
git init

在專案資料夾建立 Jekyll 的 template 檔案

1
jekyll new .

此時應該會看到 jekyll 預設產生的檔案

1
2
$ ls
404.html about.md _config.yml Gemfile Gemfile.lock index.md _posts

將所有產生的檔案 add 並 commit 起來 (要不要略過 Gemfile.lock 看個人需求)

1
2
git add .
git commit

之後將專案 push 上 GitHub,並至專案設定內啟用 GitHub Page 即可。 沒意外的話,大概十秒內就可以在對應的 URL 看到生成好的網站了。

有關 Jekyll 的安裝說明或其他細部設定,可參考 官方網站

在 GitHub Page 服務上使用個人客製的網址

如果不想使用 <username>.github.io 來提供自己的網站,而是透過自己購買的域名, 所需的麻煩差事 GitHub Page 也幫我們做得好了。

在 GitHub 專案開啟 GitHub Page 功能後,可以看到一個額外的選項 Custom domain, 可以填入我們可控制的 DNS hostname。

假設我們想在 blog.example.com 提供我們的網站,只需要在 DNS 設定中加入一筆 CNAME,將 blog.example.com 指向 <username>.github.io。並去 GitHub Page 所用的 GitHub 專案設定頁面內,在 Custom domain 欄位內填入 blog.example.com 即可。

設定完後,即可透過 blog.example.com 瀏覽我們要的網站。 同時 GitHub 也會在一天內生出對應的 SSL 憑證,即使透過 blog.example.com 瀏覽, 也可以享有 HTTPS protocol 帶來的安全性。 :D

雜談

大概從 2018 十月開始,小弟我在與朋友以及公司同事談話後,漸漸有了經營自己 Blog 的想法。

經歷了數週的拖拉散漫後,終於在 2018 十二月底刷卡買了自己的 domain,並利用 GitHub Page 架設好 Blog。但因為一直沒想好要寫什麼文章,於是第一篇就先來寫寫 我自己的架站筆記。

期許自己未來能不斷產出新文章,成為一位散發正面能量的一倍工程師。