常見的 Caddyfile 模式
本頁展示了一些完整且精簡的 Caddyfile 設定,適用於常見的使用情境。這些可以作為您自己的 Caddyfile 文件的實用起點。
這些不是直接可用的解決方案;您需要自訂您的網域名稱、連接埠/sockets、目錄路徑等等。它們旨在說明一些最常見的設定模式。
靜態檔案伺服器
example.com {
root * /var/www
file_server
}
如同往常,第一行是網站位址。root
指令 指定網站根目錄的路徑 (*
表示比對所有請求,以便與 路徑匹配器 區分)—如果路徑不是目前的工作目錄,請變更為您的網站路徑。最後,我們啟用了靜態檔案伺服器。
反向代理
代理所有請求
example.com {
reverse_proxy localhost:5000
}
僅代理路徑以 /api/
開頭的請求,並為其他所有內容提供靜態檔案
example.com {
root * /var/www
reverse_proxy /api/* localhost:5000
file_server
}
這使用 請求匹配器 僅比對以 /api/
開頭的請求,並將其代理到後端。所有其他請求將從網站的 root
透過 靜態檔案伺服器 提供。這也取決於 reverse_proxy
在 指令順序 上高於 file_server
。
這裡有更多 reverse_proxy
範例。
PHP
PHP-FPM
在 PHP FastCGI 服務運作的情況下,類似這樣的配置適用於大多數現代 PHP 應用程式
example.com {
root * /srv/public
encode
php_fastcgi localhost:9000
file_server
}
相應地自訂網站根目錄;此範例假設您的 PHP 應用程式的 webroot 在 public
目錄中—對磁碟上存在的檔案的請求將由 file_server
提供,而其他任何內容將路由到 index.php
以由 PHP 應用程式處理。
您有時可以使用 unix socket 連接到 PHP-FPM
php_fastcgi unix//run/php/php8.2-fpm.sock
php_fastcgi
指令 實際上只是 幾個配置片段 的捷徑。
FrankenPHP
或者,您可以使用 FrankenPHP,它是 Caddy 的一個發行版,它使用 CGO (Go 到 C 的綁定) 直接呼叫 PHP。這可能比 PHP-FPM 快 4 倍,如果您可以使用 worker 模式,效果會更好。
{
frankenphp
order php_server before file_server
}
example.com {
root * /srv/public
encode zstd br gzip
php_server
}
重新導向 www.
子網域
要使用 HTTP 重新導向新增 www.
子網域
example.com {
redir https://www.{host}{uri}
}
www.example.com {
}
要移除它
www.example.com {
redir https://example.com{uri}
}
example.com {
}
要一次為多個網域移除它;這使用了 {labels.*}
佔位符,它們是主機名稱的組成部分,從右側以 0
為索引 (例如 0
=com
, 1
=example-one
, 2
=www
)
www.example-one.com, www.example-two.com {
redir https://{labels.1}.{labels.0}{uri}
}
example-one.com, example-two.com {
}
尾部斜線
您通常不需要自己設定這個;file_server
指令 會根據請求的資源是目錄還是檔案,透過 HTTP 重新導向自動新增或移除請求中的尾部斜線。
但是,如果您需要,您仍然可以使用您的設定強制執行尾部斜線。有兩種方法可以做到:內部或外部。
內部強制執行
這使用 rewrite
指令。Caddy 將在內部重寫 URI 以新增或移除尾部斜線
example.com {
rewrite /add /add/
rewrite /remove/ /remove
}
使用重寫,帶有和不帶尾部斜線的請求將會相同。
外部強制執行
這使用 redir
指令。Caddy 將要求瀏覽器變更 URI 以新增或移除尾部斜線
example.com {
redir /add /add/
redir /remove/ /remove
}
使用重新導向,用戶端將必須重新發出請求,為資源強制執行單一可接受的 URI。
萬用字元憑證
如果您需要使用相同的萬用字元憑證服務多個子網域,處理它們的最佳方式是使用像這樣的 Caddyfile,利用 handle
指令 和 host
匹配器
*.example.com {
tls {
dns <provider_name> [<params...>]
}
@foo host foo.example.com
handle @foo {
respond "Foo!"
}
@bar host bar.example.com
handle @bar {
respond "Bar!"
}
# Fallback for otherwise unhandled domains
handle {
abort
}
}
您必須啟用 ACME DNS 挑戰,才能讓 Caddy 自動管理萬用字元憑證。
單頁應用程式 (SPA)
當網頁執行自己的路由時,伺服器可能會收到大量針對伺服器端不存在的頁面的請求,但只要改為提供單一索引檔案,這些頁面就可以在用戶端呈現。像這樣架構的 Web 應用程式稱為 SPA 或單頁應用程式。
主要概念是讓伺服器「嘗試檔案」以查看請求的檔案是否存在於伺服器端,如果不存在,則回退到索引檔案,由用戶端進行路由 (通常使用用戶端 JavaScript)。
典型的 SPA 設定通常看起來像這樣
example.com {
root * /srv
encode
try_files {path} /index.html
file_server
}
如果您的 SPA 與 API 或其他僅限伺服器端的端點耦合,您會想要使用 handle
區塊來獨佔處理它們
example.com {
encode
handle /api/* {
reverse_proxy backend:8000
}
handle {
root * /srv
try_files {path} /index.html
file_server
}
}
如果您的 index.html
包含對具有雜湊檔名的 JS/CSS 資源的參考,您可能會想要考慮新增 Cache-Control
標頭以指示用戶端不要快取它 (以便在資源變更時,瀏覽器會提取新的資源)。由於 try_files
重寫用於從任何與磁碟上其他檔案不符的路徑提供您的 index.html
,您可以將 try_files
包裹在 route
中,以便 header
處理程序在重寫之後執行 (由於 指令順序,它通常會在之前執行)
route {
try_files {path} /index.html
header /index.html Cache-Control "public, max-age=0, must-revalidate"
}
Caddy 代理到另一個 Caddy
如果您有一個公開可存取的 Caddy 實例 (我們稱之為「前端」),而另一個 Caddy 實例在您的私有網路中 (我們稱之為「後端」) 提供您的實際應用程式,您可以使用 reverse_proxy
指令 來傳遞請求。
前端實例
foo.example.com, bar.example.com {
reverse_proxy 10.0.0.1:80
}
後端實例
{
servers {
trusted_proxies static private_ranges
}
}
http://foo.example.com {
reverse_proxy foo-app:8080
}
http://bar.example.com {
reverse_proxy bar-app:9000
}
-
此範例服務兩個不同的網域,將兩者都代理到同一個後端 Caddy 實例,連接埠為
80
。您的後端實例以不同的方式服務這兩個網域,因此它配置了兩個獨立的站點區塊。 -
在後端,
http://
用於在連接埠80
上接受 HTTP。前端實例終止 TLS,並且前端和後端之間的流量在私有網路上,因此無需重新加密。 -
如果需要,您可以在後端實例上使用不同的連接埠,例如
8080
;只需將:8080
附加到後端設定中的每個站點位址,或者將http_port
全域選項 設定為8080
。 -
在後端,
trusted_proxies
全域選項 用於告知 Caddy 信任前端實例作為代理。這確保了真實的用戶端 IP 被保留。 -
更進一步,您可以有多個後端實例,您可以在它們之間進行 負載平衡。您可以使用前端實例上的
acme_server
設定 mTLS (相互 TLS),使其充當後端實例的 CA (如果前端和後端之間的流量跨越不受信任的網路,這會很有用)。