這是本站的第一篇文章。第一篇不寫別的,先交代這個網站本身是怎麼來的——因為對我來說,選型的過程比選型的結果更能說明一個人怎麼思考。
我的日常工作是資安顧問。這代表一件事:這個網站不只是我的發布平台,它本身就是我專業的一部分展示品。一個資安從業者的網站如果被掛馬、被植入惡意腳本,那不是運維事故,是聲譽事故。所以整個選型只從一個問題出發:
我能不能讓這個網站,沒有東西可以被攻擊?
從攻擊面開始想,而不是從功能開始想 Link to heading
大多數人架部落格的思考順序是:我要什麼功能(留言、後台、外掛)→ 選一個滿足功能的系統 → 再想辦法把它加固。
我把順序倒過來:先問這個網站必須有什麼,其他一律不要。
答案很短——它必須能被讀、能被搜尋引擎索引、能訂閱。就這樣。它不需要後台(我在自己的電腦上寫作)、不需要資料庫(文章就是檔案)、不需要任何伺服器端的執行環境(沒有動態內容)。
把這個需求清單攤開,結論自己浮出來:純靜態網站。
| 面向 | 動態系統(如 WordPress) | 純靜態(本站) |
|---|---|---|
| 伺服器端執行環境 | PHP + 資料庫 | 無 |
| 後台登入頁 | 有(永遠在被掃) | 不存在 |
| 外掛供應鏈風險 | 有,且是主要破口 | 無 |
| 需要持續修補的元件 | CMS 核心、外掛、主題、PHP、DB | 幾乎只剩 web server 本身 |
| 被入侵後能改什麼 | 資料庫、程式碼、掛馬 | 沒有可持久化的執行點 |
沒有後台,就沒有暴力破解;沒有資料庫,就沒有注入;沒有伺服器端程式,就沒有 RCE。這不是「加固到很難打」,是結構上沒有東西可打。剩下的攻擊面收斂到 web server 與基礎設施層,而那是一個小得多、也成熟得多的問題。
技術組合 Link to heading
本站目前的組合如下——刻意只描述到「選了什麼」的層次,部署細節不在公開範圍(這也是一種攻擊面管理):
- 產生器:Hugo — 單一執行檔、build 速度極快、對 Markdown 原生友善
- 主題:hugo-coder — 極簡、為技術寫作而生,不用跟版面纏鬥
- 寫作格式:Markdown — 文章就是版本控制裡的一個
.md檔 - 版本控制:git — 整個網站是一個 repo,source of truth 不在伺服器上
- 前端防護:CDN 反向代理 — 源站不直接面對網際網路
- 主機:自管伺服器 — 產出的靜態檔案由自己的基礎設施提供服務
為什麼是 Hugo Link to heading
靜態產生器選項很多,我最後選 Hugo 的理由很務實:
- 單一執行檔,零依賴。 不需要維護 Node 或 Ruby 的環境,
hugo一個 binary 就是全部。少一層依賴,就少一層供應鏈。 - build 快到沒有感覺。 全站重建以毫秒到秒計,寫作到預覽之間沒有等待的摩擦。
- SEO 基本件是內建的。 RSS、sitemap、語意化的 HTML 結構,不需要外掛,產生器直接生給你。
寫一篇新文章的完整流程,就這樣:
# 建立新文章
hugo new content posts/my-new-post.md
# 本地預覽(含草稿)
hugo server -D
# 產出正式版靜態檔案
hugo --minify
產出的 public/ 目錄就是整個網站——一堆 HTML、CSS 和圖片,複製到任何一台 web server 上就能跑。
備份策略:git 就是備份 Link to heading
因為整個網站是一個 git repo,備份問題被降維成「repo 放幾份」的問題:
- 遠端 git 託管一份
- 自有基礎設施一份
- 工作機本地一份
災難復原等於 git clone 加一次 hugo build,以分鐘計。沒有資料庫要倒、沒有系統狀態要還原——網站的完整狀態就是版本控制的最新 commit,這順便解決了「改壞了怎麼退回」的問題:git revert,結束。
這個網站接下來會寫什麼 Link to heading
我的主題會集中在一件事上:AI 輔助開發的可信驗證——當 AI 開始大量寫程式碼、甚至開始審查程式碼,我們怎麼知道哪些產出可以信?
第一篇正式文章已經在路上,先留一個問題給你:
當你用一個 AI 去審查另一個 AI 寫的程式碼,你得到的是「驗證」,還是只是「第二個會犯錯、而且會被騙的意見」?
如果這個問題讓你停了一秒,歡迎訂閱 RSS,下一篇見。
本文同時是本站的渲染測試:標題階層、表格、程式碼區塊、引用、清單與連結,都在這一篇裡走過一遍。