前言

最近想把學習過程和筆記整理成網誌,選擇了 Hugo 這個 static site generator。因為運行環境是 Proxmox VE 上的 Ubuntu LXC(無特權容器),有一些需要注意的地方。這篇文章完整記錄從零開始部署 Hugo + PaperMod 主題到 Cloudflare Pages 的全过程。

環境準備

  • 作業系統:Proxmox VE 上的 Ubuntu 24.04 LXC(無特權容器)
  • 容器技術:Docker
  • Hugo 版本:使用 hugomods/hugo:exts Docker 映像檔(內含最新版 Hugo Extended)
  • 部署平台:Cloudflare Pages(免費方案)

為什麼要用 Docker?

Hugo 的安裝方式很多,有 apt 安裝、go install、官方安裝腳本等。但這裡我選擇用 Docker 的原因很簡單:

  1. 版本隔離:不需要在宿主機安裝 Hugo,不會跟其他套件衝突
  2. 隨時更新:只要拉最新的 Docker 映像檔,就是最新版 Hugo
  3. 一致性:本地開發和雲端部署使用相同環境,減少版本差異問題

而且這個專案用的 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.tomlarchetypes/ 等必要檔案。

第二步:設定 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 namemy-hugo-blog
Production branchmain
Framework presetHugo
Publish directorypublic

建置指令

hugo-gc-minify-baseURLhttps://lalio.dpdns.org/

這裡的 --baseURL 會覆蓋 hugo.toml 中的設定,確保線上網站的連結指向正確網域。

Hugo 版本設定

PaperMod 最新版要求 Hugo >= 0.146.0,而 Cloudflare Pages 預設裝的是舊版。需要在 Environment variables (advanced) 中新增:

VVaarliuaeb:lename:H0U.G1O4_6V.E0RSION

關於 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

總結

整個部署流程的核心要點:

  1. 使用 hugomods/hugo:exts Docker 映像檔 — 確保是最新版 Hugo Extended
  2. LXC 環境記得加 --network host — 避免 bridge 網路權限問題
  3. hugo.toml 用本地 baseURL,Cloudflare Build command 用線上 baseURL — 本地看草稿、線上用正式網域
  4. PaperMod 需要 Hugo >= 0.146.0 — Cloudflare 必須手動設定 HUGO_VERSION

部署完成後,每次 git pushmain 分支,Cloudflare Pages 就會自動重建和部署你的網站,完全自動化。

參考資源