Caddy-用Go寫的新一代可擴充套件WebServer

語言: CN / TW / HK

前幾天用 Netmaker 的時候發現它用 Caddy 替換掉了 Nginx,用了後發現確實簡單好用,就安利一下。

Caddy 是一個強大的、可擴充套件的平臺,用 Go 編寫,可以為你的站點、服務和應用程式提供服務。如果你是 Caddy 的新手,你服務網路的方式將會改變。

引言

大多數人使用 Caddy 作為網路伺服器或代理,但在其核心,Caddy 是一個伺服器的伺服器(a server of servers)。通過必要的模組,它可以承擔任何長時間執行的程序的角色!

配置是動態的和可通過 Caddy 的 API 匯出 。雖然不需要配置檔案,但是您仍然可以使用它們; 大多數人最喜歡的配置 Caddy 的方法是使用 Caddyfile。配置文件的格式通過配置介面卡採用多種形式,但 Caddy 的本地配置語言是 JSON

Caddy 為所有主流平臺編譯,並且沒有執行時依賴項。

新手指南

我們建議每個人不管經驗如何都要看一下我們的入門指南。它將為你提供一個全面的視角來看待你的新網路伺服器,這對你繼續學習是無價的。本教程將探索使用 Caddy 的基礎知識,並幫助您在更高的層次上熟悉它。

目的:

  • 執行守護程序
  • 試試 API
  • 給 Caddy 一個配置
  • 測試配置
  • 製作一個 Caddyfile
  • 使用配置介面卡(config adapter)
  • 從一個初始配置開始
  • 比較 JSON 和 Caddyfile
  • 比較 API 和配置檔案
  • 在後臺執行
  • 零停機時間配置過載

先決條件

  • 已安裝 caddycurl(安裝 Caddy 可以參考這裡

要啟動 Caddy 作為一個守護程式,使用 run 子命令:

bash caddy run

預設情況下,Caddy 的配置(“ config”)為空。我們可以使用另一個終端訪問管理 API 來驗證這一點:

bash curl localhost:2019/config/

{% note info %} ℹ️ 資訊

上面地址不是你的網站,localhost:2019 是用來控制 Caddy 的管理端點,並被預設限制為本機訪問。 {% endnote %}

我們可以通過給它一個配置來使 Caddy 變得有用。這可以通過多種方式完成,但是我們將在下一節使用 curl/load 端點發出 POST 請求。

你的第一個配置

為了準備我們的請求,我們需要做一個配置。

將其儲存到 JSON 檔案中(例如 caddy.JSON) :

json { "apps": { "http": { "servers": { "example": { "listen": [":2015"], "routes": [ { "handle": [{ "handler": "static_response", "body": "Hello, world!" }] } ] } } } } }

然後上傳:

bash curl localhost:2019/load \ -X POST \ -H "Content-Type: application/json" \ -d @caddy.json

我們可以通過如下命令驗證 Caddy 將我們的新配置應用到另一個 GET 請求:

bash curl localhost:2019/config/

然後測試新的配置:

bash $curl localhost:2015 Hello, world!

如果你看到 Hello, world! 那恭喜了,成功了!確保配置按預期的方式工作總是一個好主意,尤其是在部署到生產環境之前。

你的第一個 Caddyfile

另一種配置 Caddy 的方法是 Caddyfile。上面我們在 JSON 編寫的配置可以簡單地表達為:

```Caddyfile :2015

respond "Hello, world!" ```

將其儲存到工作目錄檔案中名為 Caddyfile (無副檔名)的檔案中。

如果 Caddy 已經在執行, (Ctrl + c)停止它,然後執行:

bash caddy adapt

或者你把 Caddyfile 儲存在別的地方,或者給它取了別的名字:

bash caddy adapt --config /path/to/Caddyfile

您將看到 JSON 輸出! 這裡發生了什麼?

我們只是使用配置介面卡將 Caddyfile 轉換為 Caddy 的原生 JSON 結構。

雖然我們可以獲得這個輸出併發出另一個 API 請求,但是我們可以跳過所有這些步驟,因為 caddy 命令可以為我們完成這些操作。如果工作目錄中有一個叫 Caddyfile 的檔案,並且沒有指定其他配置,Caddy 會載入 Caddyfile,為我們改編,然後馬上執行。

現在當前資料夾中有一個 Caddyfile,讓我們再次執行 caddy:

bash caddy run

或者如果你的 Caddyfile 在其他地方:

bash caddy run --config /path/to/Caddyfile

(如果呼叫的是不以“ Caddyfile”開頭的其他名稱,則需要指定 --adapter caddyfile)

正如你所看到的,有幾種方法可以讓你使用初始配置啟動 Caddy:

  • 在工作目錄一個名為 Caddyfile 的檔案
  • --config flag (可選項,帶有--adapter flag)
  • --resume flag (如果先前載入了配置)

JSON vs. Caddyfile

現在您知道了,Caddyfile 剛剛為您轉換為 JSON。

Caddyfile 看起來比 JSON 簡單,但是你應該一直使用它嗎?每種方法都有利有弊。答案取決於您的需求和用例。

| JSON | Caddyfile | | :----------------------------------------------------------- | :-------------------------------------------------------------------- | | 完整的 Caddy 功能 | 最常見的 Caddy 功能部件 | | 易於生成 | 易於手工製作 | | 易於程式設計 | 難以自動化 | | 非常有表現力 | 適度的表達 | | 允許配置遍歷 | 不能在 Caddyfile 間轉換 | | 部分配置更改 | 只能修改整個配置 | | 可以匯出 | 無法匯出 | | 與所有 API 端點相容 | 與某些 API 端點相容 | | 自動生成的文件 | 文件是手寫的 | | 無處不在 | 小眾 | | 更有效率 | 更多的計算 | | 有點無聊 | 挺有意思的 | | 瞭解更多:JSON 結構 | 瞭解更多:Caddyfile 文件 |

您將需要決定哪一個最適合您的用例。

需要注意的是,JSON 和 Caddyfile (以及任何其他支援的配置介面卡)都可以與 Caddy 的 API 一起使用。然而,如果您使用 JSON,您將獲得 Caddy 的全部功能和 API 特性。如果使用配置介面卡,使用 API 載入或更改配置的唯一方法是 /load 端點

API vs. 配置檔案

{% note info %} ℹ️ 資訊

實際上,即使是配置檔案也要經過 Caddy 的 API 端點,命令只是為您包裝了這些 API 呼叫。 {% endnote %}

您還需要決定您的工作流是基於 API 的還是基於 CLI 的。(您可以在同一臺伺服器上同時使用 API 和配置檔案,但我們不推薦這樣做: 最好有一個真實的來源。)

| API | 配置檔案 | | :----------------------------------------------------------------- | :----------------------------------------------------------------------------- | | 使用 HTTP 請求修改配置 | 使用 shell 命令修改配置 | | 易於擴大規模 | 難以規模化 | | 手工操作難度大 | 易於手工操作 | | 真的很有趣 | 也很有趣 | | 瞭解更多:API 教程 | 瞭解更多:Caddyfile 教程 |

{% note info %} ℹ️ 資訊

使用 API 手動管理伺服器配置完全可以通過適當的工具實現,例如: 任何 REST 客戶端應用程式 {% endnote %}

或配置檔案工作流的選擇與配置介面卡的使用是正交的: 你可以使用 JSON,但儲存在一個檔案中,並使用命令列介面; 相反,你也可以使用 Caddyfile 與 API。

但是大多數人會使用 json + api 或 Caddyfile + CLI 組合。

如您所見,Caddy 非常適合於各種各樣的用例和部署!

Start,stop,run

因為 Caddy 是一個伺服器,所以它可以無限期地執行。這意味著在執行 caddy run 之後,終端不會解除阻塞,直到程序終止(通常使用 Ctrl + c)。

雖然 caddy run 是最常見的,通常是推薦的(特別是在進行系統服務時!),你也可以選擇使用 caddy start 啟動 Caddy,並讓它在後臺執行:

bash caddy start

這將允許您再次使用您的終端,這在一些互動式無頭環境中非常方便。

然後你必須自己停止這個過程,因為 Ctrl + c 不會為你停止:

bash caddy stop

或者使用 API 的/stop 端點

重新載入配置

您的伺服器可以執行零停機時間配置過載/更改。

載入或更改配置的所有 API 端點都是完美的,並且沒有停機時間。

但是,在使用命令列時,可能很容易使用 Ctrl + c 來停止伺服器,然後再重新啟動伺服器以獲取新的配置。不要這樣做: 停止和啟動伺服器與配置更改是正交的,並將導致停機。

相反,使用 caddy reload 命令來優雅地修改配置:

bash caddy reload

這實際上只是在引擎蓋下使用了 API。它將載入並在必要時將配置檔案調整為 JSON,然後在不停機的情況下優雅地替換活動配置。

如果載入新配置時出現任何錯誤,Caddy 將回滾到上次工作的配置。

{% note info %} ℹ️ 資訊

從技術上講,新配置是在停止舊配置之前啟動的,因此在很短的時間內,兩個配置都在執行!如果新配置失敗,它將中止一個錯誤,而舊配置則根本不會停止 {% endnote %}

Caddy 常用功能

  1. 靜態檔案訪問
  2. 反向代理
  3. HTTPS

靜態檔案訪問

命令列方式

在終端中,切換到站點的根目錄並執行:

bash caddy file-server

如果你得到一個許可權錯誤,這可能意味著你的作業系統不允許你繫結到低埠---- 所以改用高階口:

bash caddy file-server --listen :2015

然後在瀏覽器中開啟 (或 )檢視您的網站!

如果你沒有索引檔案,但是你想要顯示一個檔案列表,可以使用 --browse 選項:

bash caddy file-server --browse

您可以使用另一個資料夾作為站點根目錄:

bash caddy file-server --root ~/mysite

Caddyfile 方式

在站點的根目錄中,建立一個名為 Caddyfile 的檔案,其中包含以下內容:

```Caddyfile localhost

file_server ```

或:

```Caddyfile localhost

file_server browse ```

```Caddyfile localhost

root * /home/me/mysite file_server ```

分別對應以上的幾個命令。

反向代理

本教程假設您有一個執行在 127.0.0.1:9000 上的後端 HTTP 服務。

命令列方式

很直白,直接能看明白:

bash caddy reverse-proxy --to 127.0.0.1:9000

如果你沒有許可權繫結到低埠,你可以從高階口代理:

bash caddy reverse-proxy --from :2016 --to 127.0.0.1:9000

Caddyfile 方式

直接上配置:

```Caddyfile localhost

reverse_proxy 127.0.0.1:9000 ```

caddy run 執行即可

更改代理的地址很容易:

```Caddyfile :2016

reverse_proxy 127.0.0.1:9000 ```

更改 Caddyfile 時,請確保重新載入 Caddy (或停止並重新啟動它)。

使用反向代理指令以做很多事情。

HTTPS

本指南將向您展示如何立即使用完全自管理的 HTTPS 啟動和執行。

{% note info %} ℹ️ 資訊

在預設情況下,Caddy 對所有站點使用 HTTPS,只要在配置中提供了主機名。本教程假設您希望通過 HTTPS 獲得一個公共受信任的站點(即不是“ localhost”) ,因此我們將使用一個公共域名和外部埠 {% endnote %}

先決條件:

  • 對 DNS 的基本瞭解
  • 註冊的公共域名
  • 對埠80和443的外部訪問
  • 已安裝 caddycurl

在本教程中,將 example.com 替換為您的實際域名。

設定域名的 A/AAAA 記錄指向伺服器。您可以通過登入到您的 DNS 提供商和管理您的域名來做到這一點。

在繼續之前,用權威 lookup 驗證正確的記錄。用你的域名替換 example.com,如果你使用的是 IPv6,把 type=A 替換為 type=AAAA:

bash curl "https://cloudflare-dns.com/dns-query?name=example.com&type=A" \ -H "accept: application/dns-json"

{% note info %} ℹ️ 提示

一切的前提是你是在 cloudflare 上買的這個域名。 如果不是的話,步驟會複雜一些。 參見這篇 域名在 DNSPod 上的證書申請方式 {% endnote %}

還要確保您的伺服器在埠80和443上是可以從公共介面訪問的。

{% note info %} ℹ️ 提示

如果您在您的家庭或其他受限制的網路,您可能需要轉發埠或調整防火牆設定 {% endnote %}

所有我們需要做的是開始用您的域名配置 Caddy。有幾種方法可以做到這一點。

Caddyfile

這是獲取 HTTPS 的最常用方法。

建立一個名為 Caddyfile (無副檔名)的檔案,其中第一行是您的域名,例如:

```Caddyfile example.com

respond "Hello, privacy!" ```

然後從同一個目錄中執行:

bash caddy run

您將看到 Caddy 提供一個 TLS 證書,並通過 HTTPS 服務您的站點。這是可能的,因為你的網站在 Caddyfile 中的地址包含一個域名。

file-server 命令

bash caddy file-server --domain example.com

可以了。

reverse-proxy 命令

bash caddy reverse-proxy --from example.com --to localhost:9000

總結

Caddy 吸引我的地方:

  1. 自動申請續約證書
  2. 簡單命令的 Caddyfile
  3. Go 編寫,Caddy 為所有主流平臺編譯,並且沒有執行時依賴項。

👍👍👍

參考資料

三人行, 必有我師; 知識共享, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.