前言
最近想把學習過程和筆記整理成網誌,選擇了 Hugo 這個 static site generator。因為運行環境是 Proxmox VE 上的 Ubuntu LXC(無特權容器),有一些需要注意的地方。這篇文章完整記錄從零開始部署 Hugo + PaperMod 主題到 Cloudflare Pages 的全过程。
環境準備
- 作業系統:Proxmox VE 上的 Ubuntu 24.04 LXC(無特權容器)
- 容器技術:Docker
- Hugo 版本:使用
hugomods/hugo:extsDocker 映像檔(內含最新版 Hugo Extended) - 部署平台:Cloudflare Pages(免費方案)
為什麼要用 Docker?
Hugo 的安裝方式很多,有 apt 安裝、go install、官方安裝腳本等。但這裡我選擇用 Docker 的原因很簡單:
- 版本隔離:不需要在宿主機安裝 Hugo,不會跟其他套件衝突
- 隨時更新:只要拉最新的 Docker 映像檔,就是最新版 Hugo
- 一致性:本地開發和雲端部署使用相同環境,減少版本差異問題
而且這個專案用的 hugomods/hugo:exts 映像檔內建的是 Hugo Extended 版本,支援 SCSS/SASS 編譯——PaperMod 主題需要這個功能。
第一步:建立 Hugo 網站
在 LXC 環境中,因為是無特權容器,sysctl 權限有限,Docker 的 bridge 網路常常建立失敗。所以所有 docker run 指令都要加上 --network host。
先建立專案目錄:
mkdir -p /root/lab/apps/hugo
然後用 Docker 初始化 Hugo 網站:
cd /root/lab/apps/hugo
docker run --rm --network host --volume "$(pwd)/hugo-site:/src" hugomods/hugo:exts hugo new site hugo-site
執行完畢後,/root/lab/apps/hugo/hugo-site/ 目錄就會生成,裡面包含 hugo.toml、archetypes/ 等必要檔案。
第二步:設定 Docker Compose 預覽環境
建立 docker-compose.yaml 方便本地開發時預覽:
services:
hugo_preview:
image: hugomods/hugo:exts
container_name: hugo_preview
volumes:
- ./hugo-site:/src
working_dir: /src
ports:
- "7001:1313"
command: hugo server --bind 0.0.0.0 --port 1313 --baseURL http://192.168.88.5:7001/
啟動容器:
cd /root/lab/apps/hugo/
docker compose up -d
打開 http://192.168.88.5:7001/ 就能預覽 Hugo 網站了。
注意:LXC 無特權容器的
network_mode: host設定在 Docker Compose 中可能報錯,所以這裡用ports映射代替。
第三步:安裝 PaperMod 主題
PaperMod 是 Hugo 最流行的主題之一,預設支援暗黑模式,非常適合開發者使用。
cd /root/lab/apps/hugo/hugo-site/
git init
git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
接著編輯 hugo.toml:
baseURL = 'http://192.168.88.5:7001/'
languageCode = 'zh-tw'
title = '凱凱的個人網誌'
theme = 'PaperMod'
[params]
defaultTheme = "dark"
env = "production"
[menu]
[[menu.main]]
identifier = "posts"
name = "文章"
weight = 10
url = "/posts/"
[[menu.main]]
identifier = "about"
name = "關於我"
weight = 20
url = "/about/"
其中 baseURL 設成本地預覽地址,defaultTheme = "dark" 強制開啟暗黑模式。
第四步:撰寫第一篇文章
使用 Hugo 的指令建立新文章:
hugo new posts/hello-world.md
編輯生成的檔案,把 draft: true 改為 draft: false,並寫入文章內容。草稿文章的 draft: true 意味著本地預覽不會顯示,但 push 到 GitHub 後也不會出現在正式網站上。
同時建立「關於我」頁面:
hugo new about.md
第五步:設定 Git 與推送 GitHub
建立 .gitignore 排除不需要的檔案:
public/
resources/
.hugo_build.lock
初始化 Git 並推送:
git add .
git commit -m "Initial commit: Hugo + PaperMod theme setup"
git branch -M main
git push -u origin main
注意:PaperMod 是透過 submodule 安裝的,推送時會一起帶過去,Cloudflare Pages 能自動 clone submodule。
第六步:部署到 Cloudflare Pages
這是整個流程中最關鍵的一步。前往 Cloudflare Pages,建立新的 Pages 專案,連接你的 GitHub repository。
建置設定
在 Project settings 頁面中填入:
| 設定項目 | 值 |
|---|---|
| Project name | my-hugo-blog |
| Production branch | main |
| Framework preset | Hugo |
| Publish directory | public |
建置指令
這裡的 --baseURL 會覆蓋 hugo.toml 中的設定,確保線上網站的連結指向正確網域。
Hugo 版本設定
PaperMod 最新版要求 Hugo >= 0.146.0,而 Cloudflare Pages 預設裝的是舊版。需要在 Environment variables (advanced) 中新增:
關於 baseURL 的設定技巧
這裡有個小訣竅:本地和線上使用不同的 baseURL。
hugo.toml中的baseURL維持本地地址(http://192.168.88.5:7001/),這樣本地預覽時才能正常看到草稿文章- Cloudflare 的 Build command 中加上
--baseURL https://lalio.dpdns.org/,部署時會覆蓋hugo.toml的設定
Hugo 的 --baseURL 指令列參數會覆蓋 config 檔案中的設定,所以兩邊互不干擾。
常見錯誤
錯誤 1:ERROR => hugo v0.146.0 or greater is required
- 原因:Cloudflare Pages 預設的 Hugo 版本太舊
- 解決:在 Environment variables 新增
HUGO_VERSION=0.146.0
錯誤 2:partial "head.html" not found
- 原因:Hugo 版本低於 PaperMod 要求的最小版本
- 解決:同上,設定正確的
HUGO_VERSION
總結
整個部署流程的核心要點:
- 使用
hugomods/hugo:extsDocker 映像檔 — 確保是最新版 Hugo Extended - LXC 環境記得加
--network host— 避免 bridge 網路權限問題 hugo.toml用本地 baseURL,Cloudflare Build command 用線上 baseURL — 本地看草稿、線上用正式網域- PaperMod 需要 Hugo >= 0.146.0 — Cloudflare 必須手動設定
HUGO_VERSION
部署完成後,每次 git push 到 main 分支,Cloudflare Pages 就會自動重建和部署你的網站,完全自動化。