簡介

Caddy 是一個年輕的 web server,以 Go 語言撰寫,特色:

  • 支援自動從 Let’s Encrypt 取得與更新 TLS 1.3 加密憑證。
  • 以 HTTPS 作為預設的通訊協定。
  • 支援 HTTP/3。
  • 支援 IPv6。
  • 不依賴其它套件或 runtime,可獨立執行,因此很適合放在容器內跑。
  • 以 production 為目標,可替代爺爺級的 Apache 或 Nginx。
  • 提供組態設定 API。
  • 支援 virtual host。
  • 支援 reverse proxy。
  • 支援 rewrite。
  • 支援壓縮。

當然其它特色還很多,但其中比較值得一提的就是上面這幾點。

下載

前面提到 Caddy 本身不用依賴其它套件,所以官方發布的就只是個單一的執行檔,撇開之後由我們自己產生的設定檔不算的話,這就是 Caddy 的全部了!也或許是這樣的緣故,Caddy 並沒有提供任何的套件包或安裝檔。

依照 Caddy 網站的路徑下載 caddy,這裡我們直接抓 Caddy 2 的版本(以下的範例也都是以 Caddy 2 為基準),抓下來的檔名因版次或平台不同會有差異,先改名成簡潔的 caddy,再幫它加一下可執行的屬性:

> chmod a+x ./caddy

靜態網頁伺服器

在 Caddy 所在位置新增一個 index.html,內容如下:

<h1>Hello Caddy!</h1>

最單純的用法,這個簡易的指令體現了 Caddy 的簡潔:

> ./caddy file-server

2019/11/30 00:36:24.301 WARN admin admin endpoint disabled
2019/11/30 00:59:38.744 INFO tls cleaned up storage units
2019/11/30 08:36:24 [INFO][cache:0xc0000d0140 Started certificate maintenance routine
2019/11/30 08:36:24 Caddy 2 serving static files on :2015

從最後一行我們可以知道埠號是 2015,Caddy 會去找當前位置下的 index.html 來顯示,因此用瀏覽器開 127.0.0.1:2015 應該會看到如下圖畫面:

Hello Caddy!

檔案伺服器

先把剛剛的 index.html 改名或刪除,再加上 --browse 來跑,--browse 表示如果找不到 index.html,就列出當前位置下的檔案:

> ./caddy file-server --browse

2019/11/30 00:36:24.301 WARN admin admin endpoint disabled
2019/11/30 08:36:24 [INFO][cache:0xc0000d0140 Started certificate maintenance routine
2019/11/30 08:36:24 Caddy 2 serving static files on :2015

從最後一行我們可以知道埠號是 2015,打開 127.0.0.1:2015 應該可以看到類似下面的畫面:

Caddy

前面指令內的 --browse 表示開啟瀏覽目前 Caddy 所在位置的目錄檔案清單 ,也就是上面看到的抓圖內容。

Caddyfile

前面都是簡單的範例,如果要做比較正規的應用,則需要一些組態設定,在 Caddy 的世界,除了用 API 之外,還支援 Caddyfile 的設定檔,API 與 Caddyfile 不同之處在於,API 必須使用 JSON 格式傳遞溝通,而 Caddyfile 的語法更像是傳統的定檔的格式,對人類來說更容易讀寫。

這裡必須再提一次這篇文章是講 Caddy 2,因為 Caddy 1 與 Caddy 2 的 Caddyfile 是不同的,雖然不同,但只是設定檔的關鍵字與格式不同,整體的 Caddyfile 語法結構還是相同的,所以還是得參考 Caddy 1 的 The Caddyfile Syntax 來了解 Caddyfile 的結構。

沿用剛才的例子,做一個簡單的 index.html,以及一個 Caddyfile 內容如下:

localhost:8080 {
  file_server
}

應該很容易理解,第一行表示監聽 localhost:8080,並且後方以大括號包住的區塊都是這組 localhost:8080 的設定。(在 Linux 針對埠號 1024 以下的常用埠號有權限限制,如果沒有權限的用戶要監聽埠號 80 的話會被系統阻擋,故要監聽 1024 以下的埠號須以 root 權限跑 Caddy。)

第二行表示啟動靜態檔案伺服,有 index.html 就會回應出去,並且未開啟目錄瀏覽。

跑起來看看:

> ./caddy run

caddy run 會自己去找同樣位置下的 Caddyfile,所以應該會看到同樣的 Hello Caddy! 網頁:

Caddy

Virtual Host

如果想要設定兩組網址,以 www1.example.com 與 www2.example.com 為例,可能的 Caddyfile 會長這樣:

www1.example.com:80 {
  root /www/www1.example.com
  file_server
}

www2.example.com:80 {
  root /www/www2.example.com
  file_server
}

在上面的例子中,我們用 root 來指定該組網址對應到的真實路徑。

結語

這篇文章介紹了 Caddy 2 的特性與 Caddyfile 的基本設定,並且只涉及到 Caddy 本身,關於 Caddy 與其它 web framework 之間的整合之後有機會再另外寫一篇。

Caddy 2 的文件還沒有很完整,想要用的人還是必須多多參考 Caddy2 網站或 Caddy wiki 的文件。