Caddy入门教程

欢迎来到 Caddy!本教程将探索使用 Caddy 的基础知识,并帮助你从宏观上熟悉它。

目标:

  • 🔲 运行守护进程

  • 🔲 尝试 API

  • 🔲 给 Caddy 提供配置

  • 🔲 测试配置

  • 🔲 创建 Caddyfile

  • 🔲 使用配置适配器

  • 🔲 从初始配置开始

  • 🔲 比较 JSON 和 Caddyfile

  • 🔲 比较 API 和配置文件

  • 🔲 在后台运行

  • 🔲 零停机时间配置重载

前提条件:

  • 基本的终端/命令行技能

  • 基本的文本编辑器技能

  • caddy
     和 curl
     在你的 PATH 中

如果你是从包管理器安装的 Caddy,Caddy 可能已经作为一个服务在运行。如果是这样,请在进行本教程之前停止该服务。

让我们开始运行它:

1
2
3
4
5
6
7
8
caddy
```

哦哦;如果没有子命令,caddy
 命令只会显示帮助文本。如果你忘记该做什么了,可以随时使用它。

要将 Caddy 作为守护进程启动,使用 run
 子命令:

caddy run

1
2
  
这会一直阻塞,但它到底在做什么呢?目前……什么也没有。默认情况下,Caddy 的配置(“config”)是空白的。我们可以通过在另一个终端中使用管理 API 来验证这一点:

curl localhost:2019/config/

1
2
3
4
5
6
7
8
9
10
  
我们可以通过给它一个配置来让 Caddy 变得有用。这可以通过多种方式完成,但我们将从使用 curl
 向 /load
 端点发起 POST 请求开始。
## 你的第一个配置

为了准备我们的请求,我们需要创建一个配置。在核心层面,Caddy 的配置只是一个 JSON 文档。

将其保存到一个 JSON 文件中(例如 caddy.json
):

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

1
2
  
然后上传它:

curl localhost:2019/load \ -H “Content-Type: application/json” \ -d @caddy.json

1
2
  
我们可以通过另一个 GET 请求来验证 Caddy 是否应用了我们的新配置:

curl localhost:2019/config/

1
2
3
  
通过在浏览器中访问 localhost:2015 或使用 curl
 来测试它是否正常工作:

curl localhost:2015Hello, world!

1
2
3
4
5
6
7
8
9
  
如果你看到了 Hello, world!
,那么恭喜你——它正常工作了!在将其部署到生产环境之前,确保你的配置按预期工作总是很重要的。
## 你的第一个 Caddyfile

这有点小题大做,只是为了一个“Hello World”。

配置 Caddy 的另一种方式是使用 **Caddyfile**
。我们在上面用 JSON 写的配置可以简单地表示为:

:2015respond “Hello, world!”

1
2
3
4
5
6
7
  
将其保存到当前目录下名为 Caddyfile
(没有扩展名)的文件中。

如果 Caddy 已经在运行,停止它(Ctrl
 + C
),然后运行:

caddy adapt

1
2
3
  
或者如果你将 Caddyfile 存储在其他位置,或者文件名不是 Caddyfile

caddy adapt --config /path/to/Caddyfile

1
2
3
4
5
6
7
8
9
10
11
  
你会看到 JSON 输出!发生了什么?

我们刚刚使用了一个 配置适配器
 将我们的 Caddyfile 转换为 Caddy 的原生 JSON 结构。

虽然我们可以将该输出用于另一个 API 请求,但我们可以跳过所有这些步骤,因为 caddy
 命令可以为我们完成。如果当前目录下有一个名为 Caddyfile 的文件,并且没有指定其他配置,Caddy 将加载 Caddyfile,为我们进行适配,并立即运行。

现在当前文件夹中有了一个 Caddyfile,让我们再次运行 caddy run

caddy run

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

caddy run --config /path/to/Caddyfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  
(如果它的文件名不是以“Caddyfile”开头,你需要指定 --adapter caddyfile
。)

你现在可以尝试再次加载你的网站,你会发现它正常工作了!

正如你所见,有几种方法可以使用初始配置启动 Caddy:
- 当前目录下名为 Caddyfile 的文件

- --config
 标志(可选与 --adapter
 标志一起使用)

- --resume
 标志(如果之前加载了配置)

## JSON 与 Caddyfile

现在你知道 Caddyfile 只是为你转换为 JSON。

Caddyfile 似乎比 JSON 更容易,但你应该总是使用它吗?每种方法都有优缺点。答案取决于你的需求和用例。
<table><thead><tr><th valign="top" style="font-weight: 700;color: rgb(0, 0, 0);border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">JSON</span></section></th><th valign="top" style="font-weight: 700;color: rgb(0, 0, 0);border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">Caddyfile</span></section></th></tr></thead><tbody><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">容易生成</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">手工编写方便</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">容易编程</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">自动化困难</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">表达能力强</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">表达能力适中</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">提供 Caddy 的全部功能</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">提供 Caddy 的大部分功能</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">允许配置遍历</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">无法在 Caddyfile 内部遍历</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">支持部分配置更改</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">只能更改整个配置</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">可以导出</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">无法导出</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">与所有 API 端点兼容</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">与部分 API 端点兼容</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">文档自动生成</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">文档手工编写</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">通用</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">小众</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">更高效</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">更耗计算资源</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">有点无聊</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">有点有趣</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><strong style="color: rgb(0, 0, 0);"><span leaf="">了解更多:JSON 结构</span></strong></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><strong style="color: rgb(0, 0, 0);"><span leaf="">了解更多:Caddyfile 文档</span></strong></td></tr></tbody></table>
你需要根据你的用例来决定哪种方式最适合。

需要注意的是,JSON 和 Caddyfile(以及任何其他支持的配置适配器)都可以与 Caddy 的 API 一起使用。然而,如果你使用 JSON,你会得到 Caddy 的全部功能和 API 特性。如果使用配置适配器,加载或更改配置的唯一方法是通过 /load
 端点。
## API 与配置文件

你还需要决定你的工作流程是基于 API 还是基于 CLI。(你可以在同一服务器上同时使用 API 和配置文件,但我们不推荐:最好有一个单一的事实来源。)
<table><thead><tr><th valign="top" style="font-weight: 700;color: rgb(0, 0, 0);border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">API</span></section></th><th valign="top" style="font-weight: 700;color: rgb(0, 0, 0);border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">配置文件</span></section></th></tr></thead><tbody><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">使用 HTTP 请求更改配置</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">使用 shell 命令更改配置</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">容易扩展</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">扩展困难</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">手动管理困难</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">手动管理方便</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">真的很有趣</span></section></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><section><span leaf="">也很有趣</span></section></td></tr><tr><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><strong style="color: rgb(0, 0, 0);"><span leaf="">了解更多:API 教程</span></strong></td><td valign="top" style="border: 1px solid rgb(214, 214, 214);padding: 6px 13px;"><strong style="color: rgb(0, 0, 0);"><span leaf="">了解更多:Caddyfile 教程</span></strong></td></tr></tbody></table>
API 或配置文件工作流程的选择与配置适配器的使用是正交的:你可以使用 JSON,但将其存储在文件中并使用命令行界面;反之,你也可以使用 Caddyfile 与 API。

但大多数人会使用 JSON+API 或 Caddyfile+CLI 的组合。

正如你所见,Caddy 非常适合各种各样的用例和部署场景!
## 启动、停止、运行

由于 Caddy 是一个服务器,它会无限期运行。这意味着在你执行 caddy run
 之后,你的终端不会被释放,直到进程被终止(通常使用 Ctrl
 + C
)。

尽管 caddy run
 是最常见且通常推荐的方式(尤其是将其作为系统服务时!),但你也可以使用 caddy start
 来启动 Caddy 并让它在后台运行:

caddy start

1
2
3
4
5
6
  
这将让你可以再次使用终端,这在某些交互式无头环境中很方便。

然后你将不得不自己停止进程,因为 Ctrl
 + C
 不会为你停止它:

caddy stop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  
或者使用 API 的 /stop
 端点。
## 重新加载配置

你的服务器可以执行零停机时间的配置重载/更改。

所有加载或更改配置的 API 端点都是平滑的,没有停机时间。

然而,当你使用命令行时,可能会忍不住使用 Ctrl
 + C
 来停止服务器,然后重新启动它以加载新的配置。不要这样做:停止和启动服务器与配置更改是正交的,这将导致停机时间。

相反,使用 caddy reload
 命令进行平滑的配置更改:

caddy reload

  
这实际上只是在底层使用了 API。它将加载并(如果需要)将你的配置文件适配为 JSON,然后平滑地替换活动配置,而不会出现停机时间。  
  
如果加载新配置时出现任何错误,Caddy 将回滚到上次正常工作的配置。  
  
  

![江达小记](/images/wechatmpscan.png)