今年春節我經過一番評估之後,決定將 G. T. Wang 部落格從原本的 WordPress 架構,更換為 Hugo 的靜態網站架構,除了熟悉新的 Hugo 架構之外,還要重新整理 G. T. Wang 部落格超過 1,500 篇舊文章,整個轉移過程歷經將近兩個月。

為什麼要改為 Hugo 架構?

更換網站 CMS 架構是規模龐大的工程,通常要花費幾個月的時間才能完成,一般的網站不會時常更換架構,我的 G. T. Wang 部落格從 2008 年成立至今,第一次更換架構是在 2015 年從 Blogger 平台更換為自行架設 WordPress,而第二次就是這一次改為 Hugo 靜態架構,以下是這次更換為 Hugo 架構的幾個原因。

WordPress 伺服器負載問題

我的 G. T. Wang 部落格在 2025 年以前是採用 WordPress 架構,在過去的四、五年中,因為工作忙碌的關係擱置了好多年沒有持續更新,而這中間我時常收到 Linode 的伺服器告警信,告訴我系統的 CPU 負載過高。

Linode 伺服器 CPU 負載過高告警信

以過去的經驗來說,這類的問題通常是因為某些 WordPress 模組內部的程式碼 bugs 或 PHP 引擎本身的問題,造成伺服器的負載異常升高,想要解決這種問題,通常就是要更新 WordPress 或 php-fpm 版本,期望新版本可以修正它的 bugs,但是通常新出現的 bugs 不會馬上就修好,所以如果真的要在短時間內解決,都要去網路上看國外的技術論壇,看看有沒有第一手的補丁(patch)可以用,如果沒有人剛好遇到類似的問題,基本上要解決就只能靠自己,基本上幾乎是無解。

另一個常見的原因就是惡意的外部網路攻擊,這類的大量異常網路流量,如果剛好會有一些運算工作的話(例如觸發搜尋功能等),也會造成伺服器的 PHP 引擎或資料庫負載過高,這種狀況最簡單的處理方式就是用人工的方式設置防火牆,阻擋攻擊流量的來源 IP 網段,但是若遇到來源 IP 網段非常分散,類似 DDOS 攻擊的方式,就沒辦法採用防火牆的方式。我之前遇到類似的狀況,實在不想逐一設置防火牆,就直接把 WordPress 的搜尋功能關了,直接採用 Google 搜尋替代。

但是無論是哪一種因素造成的伺服器負載過高,處理起來都很花時間,我實在沒時間去處理這類的問題,後來索性直接放著不處理了,因為這類的負載異常升高,通常不太會影響網頁正常運作,但是我做了二十幾年的伺服器管理者,習慣性都會把伺服器問題處理好,不可能把伺服器問題放著不管,所以我也不斷思考如何以最少的時間,解決這種伺服器維護問題。

WordPress 維護問題

WordPress 底層是用 PHP 與 MySQL/MariaDB 資料庫實作,所有的文章內容都放在 MySQL/MariaDB 資料庫中,而圖片則是放在 WordPress 的 uploads 目錄中透過 WordPress 管理,如果沒有 MySQL/MariaDB 資料庫,我根本無法判定 uploads 目錄中的各個檔案隸屬於哪一篇文章,因此所有的文章內容更動都必須透過 PHP 伺服器與 MySQL/MariaDB 資料庫運作,在伺服器轉移、資料備份與回復上都必須考慮 PHP 伺服器與 MySQL/MariaDB 資料庫,對於我這個沒時間的人來說,實在是一個負擔。

Hugo 靜態網頁架構

Hugo 是一套以 Go 語言實作的開放原始碼的靜態網站產生器,特點是具有高度靈活性以及高度的執行效能,我們可以使用簡單的 Markdown 語法編輯網頁原始內容,透過 Hugo 進行各種 CSS、JavaScript、圖片等素材的處理與最佳化,同時亦可套用樣板與佈景主題,以非常簡潔的作法產生最佳化的靜態網頁。

Hugo 本身只是一個靜態網站產生器,並不像 WordPress 這類的 CMS 有提供完善的網頁後台操作介面,所有的文章撰寫通常都是透過程式碼編輯器或 IDE 來進行,實際上就是編輯一個 Markdown 原始檔,另外加上一些網頁素材圖片而已,跟一般程式開發的模式很類似,所以 Hugo 比較適合程式設計師來使用,對於一般沒有程式開發經驗的人來說,Hugo 可能不是一個很好的選擇。

對於我個人來說,由於長期管理 Linux 伺服器的因素,絕大部分的工作都是透過 ssh 連線到 Linux 伺服器上處理的,幾乎所有的工作都在 Linux 命令列與 Vim 編輯器中完成,因此我也希望可以同時在類似的環境下撰寫部落格文章,而 Hugo 剛好符合我的需求。

關於前面提到的 WordPress 伺服器負載與維護問題,在 Hugo 架構下就完全解決了,因為 Hugo 產生的是靜態網頁架構,對於伺服器的負載是最輕的,各種效能調校可能都不用做了,而 Hugo 基本上就是一個將網站原始碼轉換為網頁的轉換器,不需要依賴其他伺服器或資料庫,所以網頁原始碼就是一些單純的 Markdown 文字檔與圖片,備份與維護都非常單純,完美解決上述這些 WordPress 問題。

綜合上述的考量,加上觀察 Hugo 在 GitHub 上面的星星數,因此決定將 G. T. Wang 部落格轉為 Hugo 架構。

WordPress 轉換為 Hugo 的過程

決定好採用 Hugo 這套新架構之後,接著就是規劃如何轉換既有 WordPress 文章內容,在 Hugo 的官方文件中有描述如何從其他的 CMS 架構轉移至 Hugo,雖然對於 WordPress 轉 Hugo 已經有很多的工具可以使用,但是我研究之後發現多數的工具都不是很成熟,多少都存在一些問題,最後我採用 wordpress-to-hugo-exporter 這個 WordPress 外掛工具先將基本的文章資料從 WordPress 轉出來,接著再自己撰寫一系列的 Python 指令稿,半人工的方式逐一處理超過 1,500 偏舊文章以及對應的圖片素材。

使用 wordpress-to-hugo-exporter 外掛匯出 WordPress 文章只要幾分鐘就解決了,它會自動產生每一篇文章的 Markdown 原始檔,理想的情況下,我們只要將這些 Markdown 原始檔案放入 Hugo 專案的目錄下,就可以透過 Hugo 自動產生新的網站內容,但是由於我過去在 WordPress 舊站中自行定義了許多 CSS 以及 HTML 語法,導致匯出文章時,出現許多需要自行修正的地方,為了修正各種小地方,我寫了十幾個 Python 指令稿去批次處理這些問題。

當程式處理完之後,也是需要人工確認有沒有問題,我花了將近兩個月,重新快速看過超過 1,500 篇文章,將需要修正的無效超連結、過時的文章都重新編修一次,工程相當浩大。

通常在更改架構之後,後面還會遇到一些小問題會持續修改,所以更換網站架構歷時幾個月都是很正常的,除非有必要,不然不會有站長喜歡時常變更架構的。

在正式轉換為 Hugo 架構之前,我用 GTmetrix 測試了一下目前網站的效能。

WordPress 架構網站效能

接著我採用了最陽春的 nginx 設定,完全沒有任何快取或最佳化處理,得到的網站效能就已經有明顯的改善了。

Hugo 架構網站效能