Caddyfile 用法与配置详解
Caddyfile 是 Caddy 服务器的配置文件,采用简洁语法管理站点和服务功能。支持全局选项块、站点块、指令及匹配器,便于配置 HTTPS、反向代理等功能。 2025-6-5 14:3:56 Author: blog.axiaoxin.com(查看原文) 阅读量:13 收藏

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 [email protected] }为 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 [email protected] # 生产环境建议设置,用于 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 服务器变得异常简单。通过理解其核心概念、指令和匹配器的用法,可以轻松地构建和维护各种复杂的站点配置。


文章来源: https://blog.axiaoxin.com/post/caddyfile-guide/
如有侵权请联系:admin#unsafe.sh