Caddy 是一个使用 Go 语言编写的可扩展服务器平台。它的核心功能是管理配置。Caddy 的原生配置格式是 JSON,但 Caddyfile 是一个内置的配置适配器,因其语法简洁明了而广受欢迎,尤其适合手动编写配置。Caddyfile 易于编写、易于理解,并足以满足大多数使用场景的需求。
虽然 Caddyfile 是配置 Caddy 的首选方式,但它作为一个配置适配器,在表达能力、灵活性和可编程性方面不如 Caddy 的原生 JSON 结构。如果需要自动化 Caddy 配置或部署,建议使用 JSON 配合 Caddy API。
Caddyfile 核心概念与结构
Caddyfile 的基本思想是:首先指定站点的地址,然后列出该站点所需的功能或特性。
基本结构:
站点块的花括号 {}
:
如果 Caddyfile 中只有一个站点块,其大括号 { }
是可选的。例如,localhost respond "Hello, world!"
等同于 localhost { respond "Hello, world!" }
。
如果配置多个站点,则必须使用花括号 {}
包裹每个站点的配置来分隔它们。在这种情况下,只有地址出现在花括号外部,而该站点的指令则出现在花括号内部。
开头的花括号 {
必须在其行的末尾,且前面有一个空格。闭合的花括号 }
必须单独占一行。
注释 (Comments):
注释以 #
符号开始,并持续到行尾。
井号 #
不能出现在标记的中间,它必须前面有空格或出现在行首。
环境变量 (Environment Variables):
可以在 Caddyfile 中使用环境变量,格式为 {$ENV}
。
环境变量在 Caddyfile 解析开始之前被替换。
它们可以展开为空值、部分标记、完整标记,甚至多行和多个标记。
也可以指定默认值,例如 {$DOMAIN:localhost}
,当环境变量不存在时会使用默认值 localhost。
全局选项块 (Global Options Block)
Caddyfile 可以以一个特殊的、没有键的全局选项块开始。
如果存在全局选项块,它必须是 Caddyfile 中的第一个块。
全局选项块用于设置适用于全局的选项,或者不特定于任何一个网站的选项。在其中,只能设置全局选项,不能使用常规的站点指令。
该块使用花括号 {}
包裹,例如:{ debug }
。
以下是全局选项块中可用的主要选项及其用法和作用的详细列表:
通用选项 (General Options)
选项 (Option) | 用法 (Usage) | 作用 (Purpose) |
---|---|---|
debug | { debug } | 启用调试模式,将默认日志级别设置为 DEBUG 。这会显示更多详细信息,对故障排除非常有用(但在生产环境中会非常详细)。 |
http_port | { http_port <port> } | 设置服务器用于 HTTP 的端口。此设置仅供内部使用,不改变客户端连接的 HTTP 端口。例如,如果内部网络将 80 端口转发到 Caddy 的不同端口(如 8080),则可以使用此选项。 |
https_port | { https_port <port> } | 设置服务器用于 HTTPS 的端口。此端口会影响 HTTPS 捕获(catch-all)以及默认 HTTPS 端口的匹配。 |
default_bind | { default_bind 10.0.0.1 } | 设置默认绑定的地址。如果站点地址未指定端口,则会使用此地址。 |
order | { order <dir1> first | last | [ before | after <dir2> ] } | 为 HTTP 处理程序指令分配执行顺序。HTTP 处理程序以顺序链的形式执行,正确的顺序至关重要。可以指定绝对顺序(first 或 last )或相对于另一个指令的相对顺序(before 或 after )。对于第三方 HTTP 处理程序模块,这尤其有用。 |
storage | { storage <module_name> { <options...> } } | 配置 Caddy 用于存储公共证书、私钥和其他资产的存储设施。默认情况下,Caddy 会将其存储在可写且持久的 $HOME 文件夹中。此选项允许指定自定义存储模块及其配置。 |
storage_clean_interval | { storage_clean_interval 7d } | 定义扫描存储中过期证书并触发续订的间隔时间。默认值为 24h 。 |
admin | { admin off | <addr> { origins <origins...> enforce_origin } } | 自定义 Caddy 的管理 API 端点。设置为 off 将禁用管理端点,但这会导致无法通过 caddy reload 命令更改正在运行服务器的配置,因为 reload 命令使用此 API。还可以配置允许连接到此端点的来源 (origins )。 |
persist_config | { persist_config off } | 控制 Caddy 是否持久化其配置。如果设置为 off ,配置将不会被持久化。 |
log | { log [ name ] { output <writer_module> ... format <encoder_module> ... level <level> include <namespaces...> exclude <namespaces...> } } | 配置命名日志器。如果未指定名称,则修改默认日志器的行为。与 HTTP 请求日志(访问日志)的 log 指令不同,此全局选项配置的是 Caddy 核心日志。 |
grace_period | { grace_period 10s } | 定义 HTTP 服务器关闭时的宽限期。在此期间,服务器不再接受新连接,空闲连接被关闭,并等待活动连接完成请求。如果客户端未在此宽限期内完成请求,服务器将被强制终止。默认情况下,宽限期是永久的。 |
shutdown_delay | { shutdown_delay 30s } | 定义在宽限期开始之前的延迟时间。在此期间,服务器仍正常运行,但 {http.shutting_down} 占位符会评估为 true ,且 {http.time_until_shutdown} 会显示到宽限期开始的时间。这对于通知健康检查器或让负载均衡器将服务器移出轮换非常有用。 |
metrics | { metrics { per_host } } | 启用 Caddy 的指标收集功能。可以使用 per_host 选项将指标与主机名关联起来。 |
TLS 选项 (TLS Options)
选项 (Option) | 用法 (Usage) | 作用 (Purpose) |
---|---|---|
auto_https | { auto_https off | disable_redirects | ignore_loaded_certs | disable_certs } | 配置 Caddy 的自动 HTTPS 功能,包括证书自动化管理和 HTTP 到 HTTPS 的重定向。可以将其设置为 off 完全禁用,或禁用重定向、忽略已加载证书或禁用证书本身。 |
email | { email admin@example.com } | 为 ACME 事务指定联系电子邮件地址。 |
default_sni | { default_sni example.com } | 设置当客户端在 TLS ClientHello 中不使用 SNI(Server Name Indication)时使用的默认 TLS ServerName。 |
fallback_sni | { fallback_sni example.com } | **(实验性)**如果配置了此选项,当原始 ServerName 不匹配缓存中的任何证书时,它将成为 ClientHello 中的 TLS ServerName。这适用于特定且小众的场景。 |
local_certs | { local_certs } | 默认情况下,所有证书都将由 Caddy 内部颁发,而不是通过 Let’s Encrypt 等公共 ACME CA 颁发。这在开发环境中作为快速切换非常有用。 |
skip_install_trust | { skip_install_trust } | 跳过 Caddy 尝试将本地 CA 的根证书安装到系统信任存储以及 Java 和 Mozilla Firefox 信任存储的步骤。 |
acme_ca | { acme_ca https://acme-staging-v02.api.letsencrypt.org/directory } | 指定 ACME CA 的目录 URL。强烈建议在测试或开发时将其设置为 Let’s Encrypt 的暂存端点。默认使用 ZeroSSL 和 Let’s Encrypt 的生产端点。 |
acme_ca_root | { acme_ca_root /path/to/ca/root.pem } | 指定一个 PEM 文件,其中包含 ACME CA 端点的受信任根证书,以防其不在系统信任存储中。 |
acme_eab | { acme_eab { key_id <key_id> mac_key <mac_key> } } | 为所有 ACME 事务指定一个外部账户绑定 (External Account Binding)。 |
acme_dns | { acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN} } | 配置用于所有 ACME 事务的 DNS 挑战提供商。需要一个带有的 DNS 提供商插件的 Caddy 自定义构建。可以传递环境变量来配置提供商,例如 CLOUDFLARE_API_TOKEN 。 |
dns | { dns <provider> ... } | 配置一个默认的 DNS 提供商,当在相关上下文中未明确指定时使用。例如,如果启用了 ACME DNS 挑战但未配置 DNS 提供商,则会使用此全局默认值。它也用于发布 Encrypted ClientHello (ECH) 配置。 |
ech | { ech <public_names...> { dns <provider> ... } } | 启用 Encrypted ClientHello (ECH) 功能。需要 Caddy 构建中包含 DNS 提供商的 caddy-dns 模块。通配符证书与 ECH 结合使用可以正确隐藏子域名,前提是客户端也支持 ECH。 |
on_demand_tls | { on_demand_tls { ask <endpoint> permission <module> } } | 配置按需 TLS(On-Demand TLS),但此选项本身不启用它。在生产环境中必须配置此选项以防止滥用。ask 子选项会使 Caddy 向给定 URL 发送 HTTP 请求,询问是否允许为某个域名颁发证书。 |
key_type | { key_type ed25519 } | 指定生成 TLS 证书的密钥类型。可选值包括 ed25519 、p256 、p384 、rsa2048 和 rsa4096 。仅在有特定需求时才更改此选项。 |
cert_issuer | { cert_issuer acme { ... } cert_issuer zerossl { ... } } | 定义 TLS 证书的颁发者(或来源)。这允许全局配置颁发者,而不是针对每个站点进行配置。可以重复此选项来配置多个颁发者,它们将按照定义的顺序被尝试。 |
renew_interval | { renew_interval 30m } | 定义扫描所有已加载和管理的证书以检查过期并触发续订的频率。默认值为 10m 。 |
cert_lifetime | { cert_lifetime 30d } | 请求 CA 颁发证书的有效期。此值用于计算 ACME 订单的 notAfter 字段。默认值为 0 ,表示 CA 将选择有效期(通常为 90 天)。此为实验性功能。 |
ocsp_interval | { ocsp_interval 2h } | 检查 OCSP 装订(OCSP staples)是否需要更新的频率。默认值为 1h 。 |
ocsp_stapling | { ocsp_stapling off } | 设置为 off 可禁用 OCSP 装订。在由于防火墙导致响应者无法访问的环境中很有用。 |
preferred_chains | { preferred_chains smallest } 或 { preferred_chains { root_common_name "ISRG Root X2" } } | 如果 CA 提供多个证书链,此选项允许指定 Caddy 应该优先选择哪个链。可以选择 smallest 来优先选择字节数最少的链,或根据 root_common_name 或 any_common_name 进行匹配。 |
服务器选项 (Server Options)
选项 (Option) | 用法 (Usage) | 作用 (Purpose) |
---|---|---|
servers | { servers [ <listener_address> ] { ... } } | 自定义 HTTP 服务器的设置,这些设置可能跨越多个站点。可以指定不同的监听地址来为不同的服务器配置选项。如果省略监听地址,则选项将应用于任何剩余的服务器。 |
servers.name | 嵌套在 servers 块中 | 为此服务器分配一个自定义名称。这通常有助于在日志和指标中通过名称识别服务器。 |
servers.listener_wrappers | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于配置监听器包装器。 |
servers.timeouts | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于配置各种超时设置,包括 read_body (读取请求体的超时)、read_header (读取请求头的超时)、write (写入响应的超时)和 idle (空闲连接的超时)。 |
servers.keepalive_interval | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于配置 HTTP Keep-Alive 连接的间隔。 |
servers.trusted_proxies | trusted_proxies static [ private_ranges ] <ranges...> | 配置信任的代理服务器,以便 Caddy 能够正确解析真实的客户端 IP 地址。可以指定静态的 IP 范围或私有 IP 范围作为信任来源。 |
servers.client_ip_headers | 嵌套在 servers 块中 | 未在提供的源中详细描述。在 trusted_proxies 启用时,用于指定包含客户端 IP 地址的 HTTP 头部名称。 |
servers.trace | 嵌套在 servers 块中 | **(实验性)**记录每个被调用的处理程序。需要将日志级别设置为 DEBUG (可通过 debug 全局选项实现)。请注意,这可能会记录 HTTP 处理程序模块的配置,因此在不安全的环境中不要启用。 |
servers.max_header_size | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于设置 HTTP 请求头的最大允许大小。 |
servers.enable_full_duplex | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于启用全双工通信。 |
servers.log_credentials | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于控制是否记录凭据信息。 |
servers.protocols | 嵌套在 servers 块中 | 未在提供的源中详细描述。用于指定服务器支持的 HTTP 协议,例如 h1 (HTTP/1.1)、h2 (HTTP/2)、h2c (HTTP/2 over cleartext) 和 h3 (HTTP/3)。 |
servers.strict_sni_host | { servers { strict_sni_host on } } | 当设置为 on 时,对 TLS SNI 主机进行严格验证。 |
其他选项
选项 (Option) | 用法 (Usage) | 作用 (Purpose) |
---|---|---|
filesystem | { filesystem foo custom { ... } filesystem bar custom { ... } } | 允许声明一个或多个文件系统。这使得 Caddy 可以连接到远程文件系统、具有文件接口的数据库,甚至是从 Caddy 二进制文件中读取嵌入式文件。每个文件系统都通过一个名称来标识。Caddy 默认不包含任何文件系统模块,需要构建带有相应插件的 Caddy。 |
pki | { pki { ca local { name <name> root_cn <name> intermediate_cn <name> intermediate_lifetime <duration> root { ... } intermediate { ... } } } } | PKI (Public Key Infrastructure) 应用程序的选项。此应用程序是 Caddy 本地 HTTPS 和 ACME 服务器功能的基础。它定义了能够签署证书的证书颁发机构 (CA)。默认的 CA ID 为 local 。 |
events | { events { on <event> <handler...> } } | 配置事件处理程序。Caddy 模块在发生重要事件时(或即将发生时)会发出事件。事件通常包含元数据负载。要了解事件及其负载,可以查阅模块文档,或通过启用 debug 全局选项并阅读日志来观察。 |
站点块(site block)
在可选的全局选项块之后(或如果不存在全局选项块,则作为 Caddyfile 的第一行)。
Caddyfile 由至少一个或多个站点块组成。
每个站点块总是以一个或多个站点地址开始。
多个站点:可以通过用花括号 {}
包裹每个站点块,在同一个 Caddyfile 中定义多个站点。地址之间可以使用空格或逗号分隔。
localhost {
respond "Hello, world!"
}
localhost:2016 {
respond "Goodbye, world!"
}
地址 (Addresses)
地址用于指定 Caddy 服务的网站,可以是域名(例如 example.com、localhost、*.example.com
)、IP 地址(例如 127.0.0.1),或者包含方案(Scheme)和端口(Port)(例如 http://example.com、:8080)。
地址必须是唯一的,不能多次指定同一个地址。
地址中不能使用占位符,但可以使用 Caddyfile 风格的环境变量,例如 {$SITE_ADDRESS}
。
通配符 *
只能用于表示主机名中的一个标签,例如 *.example.com
会匹配 foo.example.com 但不匹配 foo.bar.example.com。
要捕获所有主机,可以省略地址的主机部分,例如只写 https://。
在 Caddyfile 中,地址 (Addresses) 始终出现在站点块的顶部,通常是 Caddyfile 中的第一项内容。地址定义了 Caddy 将服务哪些请求。
以下是 Caddyfile 地址用法的详细介绍:
地址示例 (Address Example) | 效果 (Effect) | 说明 (Description) | 来源 |
---|---|---|---|
example.com | HTTPS,带公共信任证书 | Caddy 会为该域名自动获取并管理公开信任的 HTTPS 证书。默认情况下,Caddy 会自动为所有站点提供 HTTPS 服务。 | |
*.example.com | HTTPS,带公共信任通配符证书 | Caddy 会为该通配符域名自动获取并管理公开信任的 HTTPS 通配符证书。这需要 DNS 挑战来获取通配符证书。自 Caddy 2.10 起,通配符证书将用于配置中的单个子域名,除非明确配置为获取独立证书。 | |
localhost | HTTPS,带本地信任证书 | 对于 localhost 或其他本地/内部主机名,Caddy 使用自动信任的自签名证书提供 HTTPS 服务。首次使用时,Caddy 可能会提示安装其唯一的根证书到的信任存储区。 | |
http:// | HTTP 全局匹配 | 捕获所有 HTTP 请求,受 http_port 全局选项影响。Caddy 会在运行时创建一个监听端口 80 (或 http_port 选项) 的服务器,用于 HTTP 到 HTTPS 的重定向和解决 ACME HTTP 挑战。 | |
https:// | HTTPS 全局匹配 | 捕获所有 HTTPS 请求,受 https_port 全局选项影响。当不预先知道所有域名时(例如,使用按需 TLS),这非常有用。 | |
http://example.com | 显式 HTTP,带 Host 匹配器 | 明确指定使用 HTTP 协议,并带有一个 Host 请求匹配器来匹配 example.com 。 | |
example.com:443 | HTTPS,因匹配默认 HTTPS 端口 | 即使没有明确指定 https:// 前缀,由于端口 443 是默认的 HTTPS 端口,Caddy 也会使用 HTTPS。 | |
:443 | HTTPS 全局匹配,因匹配默认 HTTPS 端口 | 捕获所有 HTTPS 请求,因为匹配了默认的 HTTPS 端口 (443 )。 | |
:8080 | 非标准端口上的 HTTP,无 Host 匹配器 | 在非标准端口 8080 上提供 HTTP 服务,不强制要求特定的 Host 头。 | |
localhost:8080 | 非标准端口上的 HTTPS,因有有效域名 | 在非标准端口 8080 上提供 HTTPS 服务,因为 localhost 是一个有效的域名。 | |
https://example.com:443 | HTTPS,https:// 和 :443 冗余 | 明确指定 HTTPS 协议和默认 HTTPS 端口。在这种情况下,https:// 和 :443 都是冗余的,因为它们是默认行为。 | |
127.0.0.1 | HTTPS,带本地信任 IP 证书 | 对于 IP 地址,Caddy 使用自动信任的自签名证书提供 HTTPS 服务。 | |
http://127.0.0.1 | HTTP,带 IP 地址 Host 匹配器 | 明确指定使用 HTTP 协议,并带有一个 Host 请求匹配器来匹配 127.0.0.1 。此配置会拒绝匹配 localhost 的请求。 |
Host
头匹配:如果指定了主机名(例如localhost
),Caddy 只会处理Host
头匹配的请求。这意味着如果站点地址是localhost
,Caddy 将不会匹配对127.0.0.1
的请求。- 通配符 (
*
):通配符只能用于表示主机名中的一个标签。例如,*.example.com
匹配foo.example.com
,但不匹配foo.bar.example.com
。单个*
匹配localhost
但不匹配example.com
。 - 自动 HTTPS:
- Caddy 默认自动为所有站点提供 HTTPS 服务。
- 它会自动更新和管理证书,并将 HTTP (默认端口
80
) 请求自动重定向到 HTTPS (默认端口443
)。 - 任何主机匹配器 (
host
matcher) 都会触发自动 HTTPS。 - Caddy 使用 Smallstep 库的本地 CA 为非公共站点生成和签署证书。
- 对于公共域名,Caddy 通过 ACME CA (如 Let’s Encrypt 或 ZeroSSL) 获取证书。
- 要获得公共信任证书,主机名必须符合特定要求,例如不能是
localhost
或 IP 地址,并且通配符只能是左侧的单个标签。
- 按需 TLS (On-Demand TLS):如果在启动或重新加载服务器时不知道所有域名,或者域名尚未正确配置,按需 TLS (On-Demand TLS) 非常有用。在这种情况下,可以省略地址的主机部分,例如只写
https://
。 - 端口绑定:默认情况下,站点绑定到所有网络接口。可以使用
bind
指令或default_bind
全局选项来覆盖此设置。 - 环境变量:地址中不能使用 Caddyfile 的占位符 (
{}
)。但是,可以使用 Caddyfile 风格的环境变量,它们在 Caddyfile 解析之前进行替换。例如:{$SITE_ADDRESS} file_server
。
指令 (Directives)
指令 是 Caddyfile 中 功能性关键词,用于自定义站点的服务方式。它们 必须 出现在 站点块 (site block) 内。
结构与语法:
- 指令是站点块中每行第一个单词。
- 指令可以带有 参数 (arguments),这些参数出现在指令后的同一行上。如果单个参数值中包含空格,则需要使用双引号
""
或反引号``
括起来。 - 有些指令可以开启自己的 指令块 (directive block),其中包含 子指令 (subdirectives)。子指令出现在指令块内每行的开头。
- 通常,指令不能嵌套在其他指令块内,除非它们被设计用于分组其他指令,例如
handle
和route
块。
功能和示例:
Caddy 默认提供了许多标准指令,用于实现各种功能。例如:
file_server
: 用于从磁盘提供文件服务。例如:localhost { file_server }
。reverse_proxy
: 强大且可扩展的反向代理。例如:localhost { reverse_proxy localhost:9000 }
。respond
: 将硬编码的响应写入客户端。tls
: 自定义 TLS 设置。encode
: 对响应进行编码(通常是压缩)。log
: 启用访问/请求日志记录。redir
: 向客户端发出 HTTP 重定向。root
: 设置站点根目录的路径。
指令顺序 (Directive Order):
- 许多指令会操作 HTTP 处理程序链。这些指令的评估顺序很重要,因此 Caddy 内部有一个 默认的硬编码顺序。
- 可以使用
order
全局选项 或route
指令来覆盖或自定义此顺序。 route
指令会将其内部的指令视为一个单一单元,并 保留指令出现的顺序,不受默认排序规则的影响。
配置复用:
import
指令: 用于包含代码片段或文件,以在多个站点块中复用配置。
- 如果参数与已定义的片段不匹配,Caddy 会尝试将其作为文件导入。
import
指令可以在 Caddyfile 中的任何位置出现(除了作为另一个指令的参数)。
命名路由 (Named Routes): 这是一个实验性功能,允许定义特殊的块,以 &(name)
语法开头,并在多个站点中通过 invoke
指令重复使用。这对于减少内存使用尤其有用,如果相同的路由需要在许多不同的站点中使用。
匹配器 (Matchers)
匹配器 用于根据特定条件 过滤 (classify) 请求。通过使用匹配器,可以精确指定某个指令适用于哪些请求。
语法与类型:
在 Caddyfile 中,紧随指令后的第一个参数可以是 匹配器标记 (matcher token),它限制了该指令的作用范围。匹配器标记有以下三种形式:
*
(通配符): 匹配所有请求 (默认行为)。如果省略匹配器标记,则等同于通配符匹配。/path
(路径匹配器): 以斜杠/
开头,用于匹配请求路径。- 路径匹配是精确的,但不区分大小写。
- 可以使用通配符
*
:- 仅在末尾,进行前缀匹配 (
/prefix/*
)。 - 仅在开头,进行后缀匹配 (
*.suffix
)。 - 在两边,进行子串匹配 (
*/contains/*
)。 - 在中间,进行全局匹配 (
/accounts/*/info
)。
- 仅在末尾,进行前缀匹配 (
- 在指令排序算法中,单个路径匹配器优先排序,并按特异性从最特异到最不特异排序。
@name
(命名匹配器): 指定一个 命名匹配器。- 所有非路径或通配符的匹配器都必须是命名匹配器。
- 定义语法:
@name { ... }
或单行形式@name ...
。 - 使用方法:将
@name
作为指令的第一个参数。 - 逻辑组合: 命名匹配器集中的匹配器默认是 AND 关系,即所有匹配器都必须匹配。对于更复杂的布尔逻辑,推荐使用
expression
匹配器。 示例:
此配置将 HTTP/1.1 WebSocket 请求代理到example.com { @websockets { header Connection *Upgrade* header Upgrade websocket } reverse_proxy @websockets localhost:6001 reverse_proxy localhost:8080 }
localhost:6001
,其他请求到localhost:8080
。
标准请求匹配器:
Caddy 提供了多种标准请求匹配器,它们提供了丰富的过滤条件:
client_ip <ranges...>
: 根据客户端 IP 地址或 CIDR 范围匹配请求。private_ranges
是匹配所有私有 IPv4 和 IPv6 地址范围的快捷方式。expression <cel...>
: 使用 CEL (Common Expression Language) 表达式匹配,支持复杂的布尔逻辑、Caddy 占位符以及将其他匹配器作为函数使用。file
: 匹配请求路径对应的是否存在文件。header <field> [ <value> ]
: 根据请求头字段匹配。支持精确匹配、前缀、后缀、子串匹配,以及通过!
进行否定匹配。header_regexp [ <name> ] <field> <regexp>
: 基于正则表达式匹配请求头,支持命名捕获组。host <hosts...>
: 根据Host
请求头匹配。多个host
匹配器之间是 OR 关系。method <verbs...>
: 根据 HTTP 请求方法 (verb) 匹配。多个method
匹配器之间是 OR 关系。not { <matchers...> }
: 对其内部的匹配结果取反。path <paths...>
: 根据请求路径匹配。path_regexp [ <name> ] <regexp>
: 基于正则表达式匹配请求路径,支持命名捕获组。protocol <protocol_name>
: 根据请求协议匹配,如http
,https
,grpc
,http/2+
。query <key>=<val>...
: 根据查询字符串参数匹配。同一键的多个值之间是 OR 关系,不同键之间是 AND 关系。remote_ip <ranges...>
: 根据直接对等端的 IP 地址匹配。vars <variable> <values...>
: 根据请求上下文中的变量或占位符的值匹配。支持匹配多个值(OR 关系)。vars_regexp [ <name> ] <variable> <regexp>
: 基于正则表达式匹配变量值,支持命名捕获组。
响应匹配器 (Response Matchers):
- 响应匹配器通常出现在某些指令的配置内部,用于在响应被写入客户端时做出决策。
status <code>...
: 根据 HTTP 状态码匹配,支持范围匹配(如2xx
,3xx
)。header <field> [ <value> ]
: 根据响应头字段匹配。与请求头匹配器类似,支持多种匹配方式和否定。
完整 Caddyfile 示例配置与说明
以下是一个结合了多种 Caddyfile 配置项的完整示例,包括全局选项、多个站点、常用指令和匹配器:
# 全局选项块 - 必须是文件的第一个块
{
# 启用调试模式,生成详细日志用于故障排除
debug
# 配置自动 HTTPS 相关设置
auto_https off # 禁用自动 HTTPS,通常用于本地开发或特定场景
# email admin@example.com # 生产环境建议设置,用于 ACME 注册和通知
# dns cloudflare {env.CLOUDFLARE_API_TOKEN} # 生产环境通配符证书需要DNS质询
# 配置日志记录器,不同于 HTTP 请求日志
log {
output file /var/log/caddy/caddy.log
level INFO
}
# 定义HTTP服务器的宽限期,在配置更改或停止时
grace_period 5s
# 配置本地PKI,自定义本地CA的名称
pki {
ca local {
name "My Custom Caddy Local CA"
root_cn "Custom Caddy Root CA - 2024"
}
}
}
# Snippets 或 Named Routes (可选,可在这里定义)
# 例如,定义一个通用的日志配置片段
(common_logging) {
log {
output stdout
format json
}
}
# 第一个站点块:本地开发环境的静态文件服务
# 使用环境变量设置地址,并提供默认值
{$DEV_SITE_ADDRESS:localhost:8080} {
# 导入通用日志配置片段
import common_logging
# 设置站点根目录
root * /var/www/mywebapp/public
# 启用响应压缩(Gzip和Zstandard)
encode gzip zstd
# 启用模板处理
templates
# 文件服务器,如果找不到index文件则显示目录列表
file_server browse
# 定义一个命名匹配器 `@api_path`,匹配 /api/ 路径下的所有请求
@api_path path /api/*
# 使用命名匹配器 `@api_path`,将匹配到的请求反向代理到后端API服务
handle @api_path {
reverse_proxy localhost:9001
}
# 另一个命名匹配器 `@admin_ip`,匹配特定IP地址的请求
@admin_ip client_ip 192.168.1.100
# 如果请求来自管理IP,则响应 "Admin Access Granted"
respond @admin_ip "Admin Access Granted" 200
# 捕获所有未被处理的请求
handle {
respond "Hello from Dev Server!"
}
}
# 第二个站点块:生产环境的反向代理服务,支持通配符证书和不同子域处理
*.example.com {
# 配置 TLS,使用 DNS 质询来获取通配符证书
tls {
# 假设已安装了 `caddy-dns/cloudflare` 模块
dns cloudflare {$CLOUDFLARE_API_TOKEN}
}
# 定义子域 `foo.example.com` 的处理逻辑
@foo_subdomain host foo.example.com
handle @foo_subdomain {
reverse_proxy foo_backend:8080
}
# 定义子域 `bar.example.com` 的处理逻辑
@bar_subdomain host bar.example.com
handle @bar_subdomain {
reverse_proxy bar_backend:8080
}
# 默认回退处理:如果请求的子域没有明确处理,则中止请求
handle {
abort
}
}
# 第三个站点块:一个简单的重定向示例
old-site.com {
# 将所有请求重定向到新域名
redir https://new-site.com{uri} permanent
}
运行和管理 Caddy
- 创建 Caddyfile:在工作目录中创建一个名为
Caddyfile
的文本文件(无扩展名)。 - 启动 Caddy:
- 在前台运行(推荐):
caddy run
。如果当前目录中存在Caddyfile
文件,Caddy 将自动加载、适配并运行它。如果Caddyfile
在其他位置,可以使用caddy run --config /path/to/Caddyfile
。 - 在后台运行:
caddy start
。请注意,使用caddy start
启动的进程,需要使用caddy stop
来关闭服务器。
- 在前台运行(推荐):
- 重新加载配置:
- 当更改
Caddyfile
后,可以使用caddy reload
命令来热加载更新的配置,而无需停止并重新启动 Caddy。这会向 Caddy 的管理 API 发送一个请求。 - 或者,也可以直接使用 API 发送配置。
- 当更改
- 停止 Caddy:使用
caddy stop
命令停止 Caddy 进程。 - 权限问题:
- 如果 Caddy 需要绑定到低端口(如 80 或 443),可能需要提升权限。
- 在 Linux 上,可以使用
sudo setcap cap_net_bind_service=+ep $(which caddy)
命令来授予 Caddy 绑定到低端口的权限。请记住,在替换 Caddy 二进制文件后,需要再次运行此命令。
- 查看 JSON 配置:
- 可以使用
caddy adapt
命令将Caddyfile
转换为 Caddy 的原生 JSON 配置结构。 - 示例:
caddy adapt --config /path/to/Caddyfile
。
- 可以使用
- 其他常用命令:
caddy file-server
:快速启动一个生产就绪的文件服务器。caddy reverse-proxy
:快速启动一个生产就绪的反向代理。caddy validate
:测试配置文件是否有效。caddy environ
:打印 Caddy 的环境信息,有助于排查默认配置问题。
Caddyfile 凭借其简洁的语法和强大的自动 HTTPS 功能,使得配置和管理 Web 服务器变得异常简单。通过理解其核心概念、指令和匹配器的用法,可以轻松地构建和维护各种复杂的站点配置。