這篇文章解決什麼問題

很多個人部落格卡住,不是因為不會搭站,而是因為釋出鏈路太重。每寫一篇文章都要手工改設定、手工建置、手工上傳,久而久之內容生產就斷掉了。

我這次把自己的部落格整理成一條更順手的流程:本地直接寫 Markdown,提交到 GitHub 後由 GitHub Actions 自動建置和釋出。這樣寫文章這件事,才更像持續做內容,而不是每次都做一次維運。

適用場景

  • 你做的是個人部落格、技術內容站或輕量檔案站
  • 你希望文章以 Markdown 檔案儲存在儲存庫裡
  • 你不想上 WordPress,也不想維護重後台
  • 你希望中英雙語內容能長期維護,而不是靠手工對映

如果你更想要線上後台、多人協作編輯和視覺化稽核流,那這套方式就不是最優解。

最終效果

這套鏈路跑通之後,發一篇新文章只需要這幾步:

  1. 本地生成中英雙語文章骨架
  2. 編輯兩份 Markdown
  3. 本地預覽確認內容和排版
  4. git push origin main
  5. GitHub Actions 自動部署上線

也就是說,內容生產和部署已經被拆開了。你只關心寫文章,釋出動作由自動化接手。

環境準備

我當前這套部落格棧是:

  • 框架:Astro
  • 內容層:astro:content
  • 內容格式:Markdown
  • 部署方式:靜態產物釋出
  • Web 服務:Nginx
  • 自動部署:GitHub Actions

內容目錄是雙語分開的:

src/content/posts/zh-cn/*.md
src/content/posts/en-us/*.md

同一篇文章的中英文檔案共享一個 path,站點會自動生成:

  • 中文:/posts/<path>/
  • 英文:/en/posts/<path>/

具體步驟

1. 先把內容模型定死

如果一開始內容模型不穩定,後面你每加一篇文章都要補邏輯。

我現在把部落格的文章、頁面、分類、資源都統一放進了 astro:content,關鍵點有兩個:

  • 文章用 path
  • 頁面和分類用 key

這樣做的好處是,新增內容時只增加 Markdown 檔案,不再去碰路由對映程式碼。

2. 提供一個文章腳手架命令

如果每次發文章都手工複製舊檔案,效率很快就會下降。

我在專案裡補了一個腳本:

npm run new:post -- "markdown-blog-publish-workflow" "本地写 Markdown,git push 后自动上线:我的双语博客发布流程" "Write Markdown Locally, Deploy on git push: My Bilingual Blog Publishing Workflow" writing

執行後會直接生成兩份草稿:

src/content/posts/zh-cn/markdown-blog-publish-workflow.md
src/content/posts/en-us/markdown-blog-publish-workflow.md

預設是:

draft: true

這很重要,因為它能防止你寫到一半就被自動部署出去。

3. 本地只負責寫作和預覽

寫文章時,我只做兩件事:

  1. 編輯 Markdown
  2. 本地 npm run dev

瀏覽器裡主要看這些點:

  • 首頁是否出現新文章
  • 中文和英文詳情頁是否都可存取
  • 分類和標籤是否正常聚合
  • 標題和描述是否適合 SEO

如果這一步透過,後面其實就不該再手工 SSH 釋出了。

4. 把部署動作交給 GitHub Actions

這一步是整個流程能不能真正省事的關鍵。

我現在的工作流程是:

  1. push 到 main
  2. Actions 自動 npm ci
  3. 自動 npm run build
  4. 打包 dist
  5. 透過 SSH 上傳伺服器
  6. 解壓到新的 releases/<timestamp>-<sha>
  7. 切換 current
  8. 做一次公網可存取性校驗

這意味著文章釋出已經變成標準 CI/CD 流程,而不是依賴我手工操作。

5. 生產伺服器只做靜態託管

我的一個明確原則是:伺服器不負責建置,只負責託管。

這樣有幾個直接好處:

  • 伺服器更穩定
  • 建置環境更統一
  • 回滾更簡單
  • 出問題時能快速分層定位

目前線上結構大概是:

/var/www/aitokenhacks.com/releases/<release-id>
/var/www/aitokenhacks.com/current

每次釋出都只是在切換軟連結,不是覆蓋線上目錄。

6. 給自動部署補診斷資訊

自動化不是寫完 workflow 就結束了。真正有用的自動化,出錯時要能快速說明白問題。

所以我後來又給 workflow 補了幾類診斷:

  • 缺少哪個 Deploy Secret
  • SSH 是否能連通
  • 遠端目錄是否存在
  • current 最終切到了哪個 release

這樣以後如果部署失敗,不會只看到一個抽象的紅叉,而是能很快知道問題是在 GitHub Secrets、SSH、目錄權限,還是公網驗證。

常見問題

為什麼我不直接上線上後台

因為我現在這個站的重點是內容積累和 SEO,而不是編輯器體驗。

Markdown 檔案化管理有幾個我更看重的優點:

  • 全量進入 Git
  • 可回滾
  • 可審閱
  • 內容和程式碼結構一致
  • 不依賴第三方後台可用性

雙語內容為什麼不用單檔案混寫

因為單檔案裡塞兩套 frontmatter 和兩套正文,維護成本很快會上來。

我最後選的是“雙檔案,同 path”的方式:

  • 符合 Astro 內容集合的天然工作方式
  • 正文維護最直觀
  • 不需要額外翻譯對映層

自動部署失敗最常見的原因是什麼

我這次實際踩到過的主要有兩類:

  • GitHub Actions 計費或額度問題,作業直接起不來
  • Deploy Secrets 沒配對,SSH 設定階段直接失敗

所以我現在會優先檢查:

  1. Actions 是否真的開始執行
  2. Secrets 是否齊
  3. SSH 使用者和金鑰是否有效
  4. 遠端目錄權限是否允許釋出

最後總結

如果你也在做個人技術部落格,我非常建議把“寫作”和“釋出”拆開。

寫作時,只管內容質量。 釋出時,讓 CI/CD 去做重複動作。

當你能把發文動作壓縮成“本地寫 Markdown,然後 git push”,內容站才真正進入可持續維護的狀態。