快轉到主要內容

如何使用 Hugo 架設部落格並部署到 GitHub Pages?

·2683 字· loading · loading ·
目錄
從安裝 Go 與 Hugo、認識專案結構、套用主題,到用 GitHub Actions 自動部署到 GitHub Pages。

為什麼選 Hugo / GitHub Pages
#

Hugo:

  • 靜態網站,沒有資料庫與後端,維護與資安負擔都低。
  • 用 Markdown 寫作,搭配 Git 版本控制。
  • 以 Go 寫成,渲染整個站台通常只需幾百毫秒。

GitHub Pages:

  • 免費,內建 HTTPS,也能綁自訂網域。
  • 直接掛在儲存庫上,push 就重新發布,不必自己租主機。
  • 搭配 GitHub Actions,從原始碼到上線全自動。

如果想對照 Hexo 的作法,可以參考舊文「如何使用 Hexo 在 Github Pages 上部署部落格?」。


安裝 Golang
#

Hugo 主題常以 Hugo Module 發布,而 Hugo Module 本質是 Go module,安裝這類主題需要 Go。(若主題是用 git submodule 或直接下載壓縮檔,這步可以略過)

Linux
#

https://go.dev/dl/ 看目前的穩定版,下載對應的 tarball 解壓到 /usr/local

1# 下方版本號僅為示範,請改成官網當前的穩定版
2GO_VERSION=1.27.0
3curl -LO "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
4sudo rm -rf /usr/local/go
5sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz"

/usr/local/go/bin 加進 PATH(寫進 ~/.profile~/.zshrc):

1export PATH=$PATH:/usr/local/go/bin

macOS
#

1brew install go

Windows
#

https://go.dev/dl/ 下載 .msi 安裝檔執行。

確認 Golang 安裝成功
#

1go version

安裝 Hugo
#

務必安裝 extended 版,主題大多需要它內建的 Sass 編譯器。

macOS / Linux(Homebrew)
#

1brew install hugo

Linux
#

https://github.com/gohugoio/hugo/releases 看最新版,下載 extended 的 tarball,把 hugo 放進 PATH

1# 下方版本號僅為示範,請改成 releases 頁當前的版本
2HUGO_VERSION=0.166.0
3curl -LO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
4tar -xzf "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" hugo
5sudo mv hugo /usr/local/bin/

Windows
#

1winget install Hugo.Hugo.Extended

確認 Hugo 安裝成功
#

版本字串後面要有 +extended

1hugo version

建立網站
#

以下命令會創建一個叫做「my-blog」的資料夾,並在內部初始化一個 git repository。

1hugo new site my-blog --format toml
2cd my-blog
3git init

專案結構
#

hugo new site 產生的目錄大致如下:

 1my-blog/
 2├── archetypes/   # 新文章範本;hugo new 會套用這裡的 default.md
 3├── assets/       # 需要 Hugo 處理的資源(SCSS、JS、圖片),會經過編譯、壓縮、加指紋
 4├── content/      # 所有內容,這裡的目錄結構會直接對應網址結構
 5├── data/         # 自訂資料檔(YAML/JSON/TOML),模板中用 site.Data 讀取
 6├── i18n/         # 多語系翻譯字串
 7├── layouts/      # 自訂模板;與主題同名的檔案會覆蓋主題版本
 8├── static/       # 原封不動複製到網站根目錄的檔案,如 favicon、robots.txt、CNAME
 9├── themes/       # 主題(用 submodule 或手動下載時才會有)
10├── hugo.toml     # 主設定檔(TOML / YAML / JSON 皆可;設定多時可改放 config/_default/)
11└── go.mod        # 用 Hugo Module 管理主題時才有

建置後會多出兩個目錄,通常都加進 .gitignore

  • public/hugo 產生的成品,就是要發布的整包網站。
  • resources/:圖片處理等的快取。

content 的組織方式
#

  • 章節content/ 底下的每個資料夾就是一個章節,例如 content/posts/ 對應網址 /posts/
  • 單篇文章:可以是一個 .md 檔,或是「頁面綑綁(page bundle)」,也就是一個資料夾裝著 index.md 與它用到的圖片,把文章和素材放在一起。
  • _index.mdindex.md_index.md 是章節首頁(會列出底下的文章);index.md 是一篇獨立文章。
  • Front matter:每個 .md 開頭以 --- 包住的區塊,放標題、日期、分類、標籤等中繼資料。draft: true 的文章預設不會發布。

套用主題
#

Hugo 本身不含樣式,畫面由「主題」決定。主題的安裝方式各家不同,常見有三種:

  • Hugo Module:在 hugo.toml 宣告模組路徑,hugo 建置時自動抓取(需要 Go)。
  • Git submodulegit submodule add <repo> themes/<name>
  • 直接下載:把主題解壓到 themes/<name>/

https://themes.gohugo.io/ 挑主題,實際步驟一律以該主題自己的文件為準。

Blowfish 主題為例,它建議用 Hugo Module。先初始化模組(<user>/my-blog 換成你自己的路徑):

1hugo mod init github.com/<user>/my-blog

hugo.toml 宣告要用的主題模組:

1[module]
2  [[module.imports]]
3    # 換成你選用主題的模組路徑,以下為 Blowfish
4    path = "github.com/nunocoracao/blowfish/v3"

拉取並鎖定版本:

1hugo mod get github.com/nunocoracao/blowfish/v3
2hugo mod tidy

日後升級主題:

1hugo mod get -u github.com/nunocoracao/blowfish/v3
2hugo mod tidy

go.mod 會多出一行 require。之後 hugo 建置時會自動把模組下載到快取,不需要 themes/ 目錄。


設定與寫文章
#

補上 hugo.toml 的其餘基本設定:

1baseURL = "https://<user>.github.io/"
2defaultContentLanguage = "zh-tw"
3title = "My Blog"

(各主題自己的參數,如配色、首頁版型等,通常另外放在 config/_default/params.toml,細節見主題文件)

新增一篇文章:

1hugo new content posts/hello/index.md

檔案開頭是 front matter,接著寫 Markdown。把 draft 拿掉,該篇才會被發布。

本機預覽(加 -D 連草稿一起看):

1hugo server -D

http://localhost:1313/ 就能即時預覽,存檔後畫面會自動重整。

hugo server 的本機預覽畫面,套用 Blowfish 主題
hugo server 的本機預覽畫面,套用 Blowfish 主題


產生靜態檔
#

1hugo --gc --minify
  • --minify:壓縮輸出的 HTML、CSS、JS、JSON、XML,去掉空白與註解以縮小體積。
  • --gc:建置完清掉 resources/ 快取裡不再被引用的檔案(例如換過尺寸或刪掉的圖片),避免快取越積越大。

輸出在 public/,這整包就是要發布的網站。整條流程如下:

Hugo 從 Markdown 到 GitHub Pages 的流程
Hugo 從 Markdown 到 GitHub Pages 的流程


用 GitHub Actions 部署到 GitHub Pages
#

由於最終渲染的靜態檔案會存放在 public/ 資料夾中,而其他檔案推上 github 時,顯然不能直接拿來做 page 的入口。

首先把專案推到一個 公開 的 GitHub 儲存庫(若要支援私有庫見文末補充)。
到儲存庫 Settings > Pages,把 Source 設為 GitHub Actions

新增 .github/workflows/hugo.yaml

 1name: Build and deploy
 2on:
 3  push:
 4    branches: [main]
 5  workflow_dispatch:
 6permissions:
 7  contents: read
 8  pages: write
 9  id-token: write
10concurrency:
11  group: pages
12  cancel-in-progress: false
13jobs:
14  build:
15    runs-on: ubuntu-latest
16    env:
17      # CI 版本固定住,確保每次建置一致;記得定期更新
18      HUGO_VERSION: 0.166.0
19      GO_VERSION: 1.27.0
20      TZ: Asia/Taipei
21    steps:
22      - uses: actions/checkout@v7
23        with:
24          fetch-depth: 0
25      - id: pages
26        uses: actions/configure-pages@v6
27      - uses: actions/setup-go@v7
28        with:
29          go-version: "${{ env.GO_VERSION }}"
30      - name: Install Hugo
31        run: |
32          curl -sfL -o /tmp/hugo.tar.gz \
33            "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
34          sudo tar -C /usr/local/bin -xzf /tmp/hugo.tar.gz hugo
35      - name: Build
36        run: hugo --gc --minify --baseURL "${{ steps.pages.outputs.base_url }}/"
37      - uses: actions/upload-pages-artifact@v5
38        with:
39          path: ./public
40  deploy:
41    runs-on: ubuntu-latest
42    needs: build
43    environment:
44      name: github-pages
45      url: ${{ steps.deployment.outputs.page_url }}
46    steps:
47      - id: deployment
48        uses: actions/deploy-pages@v5

沒用到 Go module 的話,可以拿掉 setup-go 那步。

推上 main (預設 branch) 後,actions 會自動建置並發布,網址為 https://<user>.github.io/<repo>/。之後每次 push 時,該 workflow 設定都會使其重新部署,也就是執行 hugo 的渲染命令去產生靜態檔。也因為 config 將入口設為 ./public,所以不會讓人在頁面上瀏覽到其他不必要的檔案。


額外補充:私有庫怎麼辦?
#

GitHub Pages 的免費方案要求「儲存庫必須是公開的」,私有庫無法發布 Pages。

若不想公開原始碼,可以改用 Cloudflare Pages 在雲端建置並發布,一樣免費。作法見另一篇「用 Cloudflare Pages 免費託管私有庫的靜態網站」。


References
#

Alpaca
作者
Alpaca
No one can stop my feet.

相關文章