Caddyfile 用法与配置详解

文章目录

Caddy 是一个使用 Go 语言编写的可扩展服务器平台。它的核心功能是管理配置。Caddy 的原生配置格式是 JSON,但 Caddyfile 是一个内置的配置适配器,因其语法简洁明了而广受欢迎,尤其适合手动编写配置。Caddyfile 易于编写、易于理解,并足以满足大多数使用场景的需求。

虽然 Caddyfile 是配置 Caddy 的首选方式,但它作为一个配置适配器,在表达能力、灵活性和可编程性方面不如 Caddy 的原生 JSON 结构。如果需要自动化 Caddy 配置或部署,建议使用 JSON 配合 Caddy API。

Caddyfile 核心概念与结构

Caddyfile 的基本思想是:首先指定站点的地址,然后列出该站点所需的功能或特性。

基本结构:

Caddyfile’s structure

站点块的花括号 {}

如果 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 处理程序以顺序链的形式执行,正确的顺序至关重要。可以指定绝对顺序(firstlast)或相对于另一个指令的相对顺序(beforeafter)。对于第三方 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 证书的密钥类型。可选值包括 ed25519p256p384rsa2048rsa4096。仅在有特定需求时才更改此选项。
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_nameany_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_proxiestrusted_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.comHTTPS,带公共信任证书Caddy 会为该域名自动获取并管理公开信任的 HTTPS 证书。默认情况下,Caddy 会自动为所有站点提供 HTTPS 服务。
*.example.comHTTPS,带公共信任通配符证书Caddy 会为该通配符域名自动获取并管理公开信任的 HTTPS 通配符证书。这需要 DNS 挑战来获取通配符证书。自 Caddy 2.10 起,通配符证书将用于配置中的单个子域名,除非明确配置为获取独立证书。
localhostHTTPS,带本地信任证书对于 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:443HTTPS,因匹配默认 HTTPS 端口即使没有明确指定 https:// 前缀,由于端口 443 是默认的 HTTPS 端口,Caddy 也会使用 HTTPS。
:443HTTPS 全局匹配,因匹配默认 HTTPS 端口捕获所有 HTTPS 请求,因为匹配了默认的 HTTPS 端口 (443)。
:8080非标准端口上的 HTTP,无 Host 匹配器在非标准端口 8080 上提供 HTTP 服务,不强制要求特定的 Host 头。
localhost:8080非标准端口上的 HTTPS,因有有效域名在非标准端口 8080 上提供 HTTPS 服务,因为 localhost 是一个有效的域名。
https://example.com:443HTTPS,https://:443 冗余明确指定 HTTPS 协议和默认 HTTPS 端口。在这种情况下,https://:443 都是冗余的,因为它们是默认行为。
127.0.0.1HTTPS,带本地信任 IP 证书对于 IP 地址,Caddy 使用自动信任的自签名证书提供 HTTPS 服务。
http://127.0.0.1HTTP,带 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)。子指令出现在指令块内每行的开头。
  • 通常,指令不能嵌套在其他指令块内,除非它们被设计用于分组其他指令,例如 handleroute 块。

功能和示例:

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),它限制了该指令的作用范围。匹配器标记有以下三种形式:

  1. * (通配符): 匹配所有请求 (默认行为)。如果省略匹配器标记,则等同于通配符匹配。
  2. /path (路径匹配器): 以斜杠 / 开头,用于匹配请求路径。
    • 路径匹配是精确的,但不区分大小写。
    • 可以使用通配符 *
      • 仅在末尾,进行前缀匹配 (/prefix/*)。
      • 仅在开头,进行后缀匹配 (*.suffix)。
      • 在两边,进行子串匹配 (*/contains/*)。
      • 在中间,进行全局匹配 (/accounts/*/info)。
    • 在指令排序算法中,单个路径匹配器优先排序,并按特异性从最特异到最不特异排序。
  3. @name (命名匹配器): 指定一个 命名匹配器
    • 所有非路径或通配符的匹配器都必须是命名匹配器。
    • 定义语法:@name { ... } 或单行形式 @name ...
    • 使用方法:将 @name 作为指令的第一个参数。
    • 逻辑组合: 命名匹配器集中的匹配器默认是 AND 关系,即所有匹配器都必须匹配。对于更复杂的布尔逻辑,推荐使用 expression 匹配器。 示例:
    example.com {
        @websockets {
            header Connection *Upgrade*
            header Upgrade websocket
        }
        reverse_proxy @websockets localhost:6001
        reverse_proxy localhost:8080
    }
    
    此配置将 HTTP/1.1 WebSocket 请求代理到 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

  1. 创建 Caddyfile:在工作目录中创建一个名为 Caddyfile 的文本文件(无扩展名)。
  2. 启动 Caddy
    • 在前台运行(推荐)caddy run。如果当前目录中存在 Caddyfile 文件,Caddy 将自动加载、适配并运行它。如果 Caddyfile 在其他位置,可以使用 caddy run --config /path/to/Caddyfile
    • 在后台运行caddy start。请注意,使用 caddy start 启动的进程,需要使用 caddy stop 来关闭服务器。
  3. 重新加载配置
    • 当更改 Caddyfile 后,可以使用 caddy reload 命令来热加载更新的配置,而无需停止并重新启动 Caddy。这会向 Caddy 的管理 API 发送一个请求。
    • 或者,也可以直接使用 API 发送配置。
  4. 停止 Caddy:使用 caddy stop 命令停止 Caddy 进程。
  5. 权限问题
    • 如果 Caddy 需要绑定到低端口(如 80 或 443),可能需要提升权限。
    • 在 Linux 上,可以使用 sudo setcap cap_net_bind_service=+ep $(which caddy) 命令来授予 Caddy 绑定到低端口的权限。请记住,在替换 Caddy 二进制文件后,需要再次运行此命令。
  6. 查看 JSON 配置
    • 可以使用 caddy adapt 命令将 Caddyfile 转换为 Caddy 的原生 JSON 配置结构。
    • 示例:caddy adapt --config /path/to/Caddyfile
  7. 其他常用命令
    • caddy file-server:快速启动一个生产就绪的文件服务器。
    • caddy reverse-proxy:快速启动一个生产就绪的反向代理。
    • caddy validate:测试配置文件是否有效。
    • caddy environ:打印 Caddy 的环境信息,有助于排查默认配置问题。

Caddyfile 凭借其简洁的语法和强大的自动 HTTPS 功能,使得配置和管理 Web 服务器变得异常简单。通过理解其核心概念、指令和匹配器的用法,可以轻松地构建和维护各种复杂的站点配置。


也可以看看