設定模型
Pingclair 在載入 Pingclairfile 時編譯設定,預先完成位址解析與匹配器編譯等工作,供後續請求使用。不支援或無效的設定會在載入時被拒絕。本頁說明 v0.2.2 的設定載入與重載方式。
🗂️ 檔案由全域選項與網站區塊組成
Section titled “🗂️ 檔案由全域選項與網站區塊組成”{ email admin@example.com}
example.com { encode zstd gzip reverse_proxy 10.0.0.10:8080 10.0.0.11:8080}
:8080 { file_server ./public}- 全域選項 寫在檔案最上方一個沒有名稱的區塊裡。它們設定不屬於任何單一網站的事:ACME 帳號的 email、Admin API、自動 HTTPS、受信任的代理,以及主機名稱上游的 DNS 重新解析。指令參考列出了所有全域選項。
- 網站區塊 以位址命名:主機、連接埠,或兩者皆有。連接埠是位址的一部分,而不是另一個指令,所以位址與監聽器不可能互相矛盾。
- 指令 是網站區塊內的敘述。有些接受參數,有些接受巢狀區塊,有些兩者都接受。
- 註解 以
#開頭,直到該行結尾。 - 含有空白的值要加引號。 時間長度必須帶單位:
30s是三十秒,在需要時間長度的地方寫一個單獨的30會被拒絕。
🧭 匹配器選出指令適用的請求
Section titled “🧭 匹配器選出指令適用的請求”具名匹配器以 @name 宣告,使用時把名稱寫在指令後面:
example.com { @api path /api/* header @api Cache-Control "no-store"
@assets path /assets/* header @assets Cache-Control "public, max-age=31536000, immutable"}handle 區塊把同一條路由的指令放在一起。一個請求只會由一個 handle 區塊回應,而沒有匹配器的 handle 會接住其他區塊沒接到的所有請求:
example.com { handle /assets/* { file_server ./assets }
handle { respond "Page Not Found" 404 }}🚦 哪一條路由回應請求
Section titled “🚦 哪一條路由回應請求”路由先依指令種類排序,第一條匹配的路由負責回應。redir、handle 與 route 排在 respond 之前,respond 又排在 reverse_proxy、php_fastcgi 與 file_server 之前。相同指令的單一路徑先比較移除尾端 * 後的長度,再將精確路徑排在同名萬用路徑之前,其餘保留檔案順序。多路徑或無路徑的匹配器排在單一路徑之後。
使用互斥的 handle 區塊區分路由,或用 route 保留書寫順序。路徑比較忽略 ASCII 大小寫,並解碼一次百分比編碼;需要區分大小寫時使用 path_regexp。handle、handle_path 與 route 在區塊前只接受 *、以 / 開頭的路徑或 @name,不接受 *.php 這類裸字串。
🧩 以片段與匯入重複使用設定
Section titled “🧩 以片段與匯入重複使用設定”片段(snippet)是以 (name) { ... } 宣告、以 import name 插入的可重用設定。呼叫端可以傳入參數與一個區塊;片段在寫著 {block} 的地方接收那個區塊:
(site) { https://{args[0]} { {block} }}
import site example.com { reverse_proxy 127.0.0.1:3000}在被匯入的檔案中定義的片段,後續的匯入都看得到。指令參數清單內的佔位符會被拒絕:Caddy 在插入片段後會重新讀取那一行,而 Pingclair 的 parser 做不到,因此會拒絕這種寫法並顯示錯誤。
🛡️ 驗證會拒絕伺服器做不到的事
Section titled “🛡️ 驗證會拒絕伺服器做不到的事”pingclair validate 會編譯檔案,並執行語法以外的檢查:指令參數、匹配器語法、憑證與金鑰檔案是否存在,以及政策限制,例如哪些對端可以設定用戶端身分相關的標頭。
沒通過這些檢查的設定不會執行。判斷失敗與否的規則有三條:
- 未實作的名稱會被指名拒絕。 Pingclair 認得 Caddyfile 格式定義的每一個名稱。對於沒有實作的名稱,它會回報該功能不存在;絕不會把它當成拼錯的字,也絕不會默默忽略。
- 不支援的選項會被拒絕。
encode br是編譯錯誤,因為沒有串流式的 Brotli 編碼器;不會自動改用 gzip。 - 語法正確但指向不存在的檔案,仍然是錯誤。 伺服器儲存庫中的
examples/full_featured.pingclair語法正確,但在它所指的憑證路徑不存在的機器上,validate仍會拒絕它。
伺服器載入檔案時也會執行相同的檢查,重載時也一樣。
🔁 重載在不重啟的情況下替換設定
Section titled “🔁 重載在不重啟的情況下替換設定”重載會重新讀取檔案、編譯,並在行程持續執行的同時把結果換上去。如果新檔案編譯失敗,先前的設定會繼續提供服務。要求重載有三種方式:
pc service reload(或systemctl reload pingclair)透過已安裝的 unit 送出SIGUSR1。sudo kill -USR1 "$(systemctl show -p MainPID --value pingclair)"直接送出同一個訊號。pingclair reload透過 Admin API 進行,並印出伺服器的判定結果。它需要admin全域選項。
systemctl reload 只能回報訊號已送達,所以伺服器的判定結果會出現在 unit 的狀態列與 journal 中。
有些變更無法透過重載套用;這時伺服器會拒絕重載並保留舊設定,而不是只套用其中一部分:
- 監聽器的變更。 新增、移除或搬移位址,或讓監聽器在明文與 TLS 之間切換,都需要重啟,因為監聽 socket 是在啟動時建立的。Unix 上從空設定啟動可第一次載入明文 HTTP;TLS 與後續拓撲變更仍需重啟。
- 全域選項。 啟動時就確定的選項(例如
trusted_proxies)作用於整個行程,修改這類政策需要重啟;行程日誌設定可重載。 - 憑證拓撲。 新增 TLS 主機名稱,或改變網站取得憑證的方式,都需要重啟。
拒絕訊息會指出是哪一項變更,例如 listener topology changed (added: …, removed: …);執行 sudo pc service restart 即可套用。
以服務方式執行說明各種重載結果。
🧭 相關頁面
Section titled “🧭 相關頁面”- Pingclairfile:完整的語言說明。
- 指令參考:所有指令與選項。
- 架構:執行編譯後設定的是什麼。
