[{"content":"這篇記錄這個站台是怎麼架起來的。重點不在「照著打指令」，而在幾個中文使用者特別容易踩到、但英文教學不會提的地方。\n為什麼不用 WordPress 理由其實很單純：\n面向 WordPress Hugo 執行層 PHP + MySQL，隨時可能有漏洞 純靜態 HTML，沒有可攻擊的執行層 維護 核心、外掛、主題都要持續更新 想更新才更新，不更新也不會被打 備份 檔案 + 資料庫 dump 複製一個資料夾 速度 需要快取外掛才勉強夠快 天生就是最快的那種 寫作 網頁後台編輯器 本機 Markdown，用慣的編輯器 代價是沒有現成的後台，所有事情都得從指令列來。對習慣 terminal 的人來說這反而是優點。\n一、安裝 Hugo Extended 不要用 apt install hugo。 Ubuntu 24.04 套件庫裡是 0.123.7，而現在多數主題（包含 PaperMod）都要求 0.146 以上，裝下去第一步建置就會失敗。\n直接抓官方的 .deb：\n1 2 3 4 cd /tmp curl -fsSLO https://github.com/gohugoio/hugo/releases/download/v0.165.0/hugo_extended_0.165.0_linux-amd64.deb sudo dpkg -i hugo_extended_0.165.0_linux-amd64.deb hugo version 輸出必須同時包含版本號和 extended：\n1 hugo v0.165.0+extended linux/amd64 extended 這個字很重要 —— 它代表這份執行檔內含 Dart Sass，大部分現代主題的 CSS 都靠它編譯。裝到非 extended 版本，主題會噴 this feature is not available in your current Hugo version。\n二、建站與主題 1 2 3 hugo new site /var/www/geek --force git clone --depth=1 https://github.com/adityatelange/hugo-PaperMod.git \\ /var/www/geek/themes/PaperMod 用 git clone 而不是 Hugo Modules，是因為 Modules 需要裝 Go。單機自架的情境下多一個依賴沒有好處。\n三、繁體中文的三個關鍵設定 這一節是整篇的重點。\n1. hasCJKLanguage = true 1 2 3 hasCJKLanguage = true languageCode = \u0026#39;zh-tw\u0026#39; defaultContentLanguage = \u0026#39;zh-tw\u0026#39; 沒開這個設定，中文文章的字數統計、閱讀時間、自動摘要會全部壞掉。\n原因是 Hugo 預設用「空白」切詞。中文句子沒有空白，所以一整篇兩千字的文章會被算成 1 個字、閱讀時間 0 分鐘，摘要則可能整段吐出來或整個空白。\n開啟後 Hugo 會改用 CJK 字元計數，一切就正常了。判斷有沒有生效很簡單：看文章列表的摘要是不是正常截斷。\n2. 網址不要放中文 1 2 [permalinks] posts = \u0026#39;/posts/:year/:month/:slug/\u0026#39; Hugo 預設拿檔名當網址。如果檔名取成 我的第一篇文章.md，網址就會變成：\n1 /posts/%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/ 這種網址貼到 Slack、LINE 或 Markdown 連結裡常常會斷掉，搜尋引擎收錄也不漂亮。\n做法：檔名一律用英文，中文標題放在 front matter 的 title。讀者看到的是中文標題，網址則保持乾淨。\n1 2 3 --- title: \u0026#34;用 Hugo 架一個繁體中文部落格\u0026#34; # 顯示用，中文 --- 檔名 hugo-nginx-letsencrypt.md → 網址 /posts/2026/09/hugo-nginx-letsencrypt/。\n3. 搜尋要為中文調參數 PaperMod 的搜尋用 Fuse.js，而它的預設值是為英文設計的：\n1 2 3 4 [params.fuseOpts] minMatchCharLength = 1 ignoreLocation = true threshold = 0.4 兩個關鍵：\nminMatchCharLength = 1 —— 英文預設要求至少 3 個字元才算命中，但中文一個字就有完整語意（「網」、「站」）。維持預設會讓短詞完全搜不到。 ignoreLocation = true —— Fuse.js 預設「關鍵字越靠近開頭分數越高」，這是英文標題的假設。中文長句裡的關鍵詞常出現在中段，不關掉的話會被評為不相關而濾掉。 四、Nginx 設定 站台原始碼放 /var/www/geek，但 Nginx 的 root 要指向 public/ 子目錄 —— 這樣 content/、themes/ 這些原始檔就不會被對外提供。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 server { listen 80; server_name zeronode-uav.duckdns.org; root /var/www/geek/public; index index.html; location / { try_files $uri $uri/ =404; } # 擋掉 .git 之類的隱藏檔 location ~ /\\. { deny all; } } 先只開 80，讓 certbot 有辦法做 HTTP-01 驗證。\n五、Let\u0026rsquo;s Encrypt 1 sudo certbot --nginx -d zeronode-uav.duckdns.org --agree-tos -m you@example.com --redirect certbot 的 nginx 外掛會自動改寫設定檔，補上 443 區塊、憑證路徑和 80 → 443 轉址。\n申請前務必先測 80 埠 這是最常見的失敗點。Let\u0026rsquo;s Encrypt 對失敗次數有上限，連續失敗會被鎖一小時，所以要先確認再送出。\n放一個測試檔：\n1 2 mkdir -p /var/www/geek/public/.well-known/acme-challenge echo ok \u0026gt; /var/www/geek/public/.well-known/acme-challenge/ping 然後從外部網路開 http://你的網域/.well-known/acme-challenge/ping。\n用手機關掉 Wi-Fi、改行動網路測是最快的方法。從伺服器自己 curl 自己的公網 IP 不算數 —— 多數家用路由器不支援 hairpin NAT，就算轉發設定正確也會連不上，測了只會誤導自己。\n如果外部確實連不通，很可能是 ISP 封鎖對外 80 埠（台灣家用線路頗常見）。這種情況要改走 DNS-01：用 DuckDNS 的 API token 寫 TXT 記錄來驗證，繞過 80 埠。\n續期 Ubuntu 的 certbot 套件會自帶 systemd timer，不需要自己寫 cron：\n1 2 systemctl list-timers | grep certbot sudo certbot renew --dry-run --dry-run 會完整跑一次模擬續期，通過就代表三個月後會自動更新。\n六、日常寫作流程 1 2 3 hugo new content posts/my-post.md # 從 archetype 建立草稿 hugo server -D # 本機預覽，含草稿，存檔即時更新 hugo --gc --minify --cleanDestinationDir # 發佈 --cleanDestinationDir 會清掉已刪除文章留在 public/ 的殘骸。沒加這個參數，刪掉的文章網址還是會活著。\n小結 真正花時間的不是安裝，是那三個中文設定。hasCJKLanguage 沒開，站台看起來會「能動但哪裡怪怪的」——字數是 0、摘要是空的，而且錯誤訊息不會告訴你原因。這種坑值得先知道。\n","permalink":"https://zeronode-uav.duckdns.org/posts/2026/09/hugo-nginx-letsencrypt/","summary":"記錄這個站台從無到有的完整過程，重點放在幾個中文使用者特別容易踩到的坑：hasCJKLanguage、網址編碼、以及搜尋功能對中文的調校。","title":"用 Hugo + Nginx + Let's Encrypt 架一個繁體中文技術部落格"},{"content":"關於這個站 這裡是我的技術筆記本，記錄工作與實驗過程中累積下來的東西：踩過的坑、繞過的彎路， 以及最後真正管用的那個做法。\n寫在這裡的主題大致包含：\n無人機與飛控：MAVLink、地面站、任務規劃 嵌入式系統：韌體、感測器整合、即時性調校 Linux 與伺服器：系統管理、網路、容器化、自架服務 開發工具：讓日常工作順手一點的各種小工具與流程 文章以繁體中文為主，程式碼與指令都可以直接複製使用。\n關於這個站怎麼架的 產生器：Hugo Extended（靜態網站，沒有資料庫、沒有後台） 主題：PaperMod 伺服器：Ubuntu 24.04 + Nginx 憑證：Let\u0026rsquo;s Encrypt，自動續期 選 Hugo 而不用 WordPress 的理由很單純：靜態檔案沒有可被攻擊的執行層， 不必操心外掛更新與資料庫備份，而且整站就是一個資料夾，搬家只要複製過去就好。\n聯絡 有任何問題或指正，歡迎來信討論。\n","permalink":"https://zeronode-uav.duckdns.org/about/","summary":"\u003ch2 id=\"關於這個站\"\u003e關於這個站\u003c/h2\u003e\n\u003cp\u003e這裡是我的技術筆記本，記錄工作與實驗過程中累積下來的東西：踩過的坑、繞過的彎路，\n以及最後真正管用的那個做法。\u003c/p\u003e\n\u003cp\u003e寫在這裡的主題大致包含：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e無人機與飛控\u003c/strong\u003e：MAVLink、地面站、任務規劃\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e嵌入式系統\u003c/strong\u003e：韌體、感測器整合、即時性調校\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLinux 與伺服器\u003c/strong\u003e：系統管理、網路、容器化、自架服務\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e開發工具\u003c/strong\u003e：讓日常工作順手一點的各種小工具與流程\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e文章以繁體中文為主，程式碼與指令都可以直接複製使用。\u003c/p\u003e","title":"關於"}]