Caddy

配置

Caddyfile

Caddyfile 的结构、地址、匹配器、片段与环境变量。

Caddyfile 是大多数人配置 Caddy 的方式。它结构简单、读写顺手,最终会被适配器转成 Caddy 原生的 JSON。

结构

Caddyfile
{
	email you@yours.com
	servers {
		trusted_proxies static private_ranges
	}
}

(snippet) {
	# 这是一段可复用的片段
	log {
		output file /var/log/access.log
	}
}

example.com {
	@post {
		method POST
	}
	reverse_proxy @post localhost:9001 localhost:9002 {
		lb_policy first
	}
	file_server /static
	import snippet
}

www.example.com {
	redir https://example.com{uri}
	import snippet
}
  • 开头的全局选项块是可选的,如果有,必须是文件里的第一个块
  • 接下来可以是片段或命名路由
  • 否则,Caddyfile 的第一行永远是站点地址
  • 所有指令和匹配器都必须写在站点块里,没有全局作用域,站点块之间也不继承
  • 只有一个站点块时,花括号可以省略

块

开花括号 { 必须在行尾,且前面有空格;闭花括号 } 必须独占一行。多个站点必须用花括号分开:

多站点
example1.com {
	root /www/example.com
	file_server
}

example2.com {
	reverse_proxy localhost:9000
}

如果一个请求同时匹配多个站点块,会选择地址最具体的那个,请求不会在站点块之间级联。

指令

指令是定制站点行为的名字,必须写在站点块里,位于行首。指令后面同一行的参数是它的实参;指令自己的块里开头的行是子指令:

reverse_proxy
localhost {
	reverse_proxy localhost:9000 localhost:9001 {
		lb_policy first
	}
}

标记与引号

Caddyfile 先被词法分析成标记,标记之间用空白分隔。参数里带空格就要加引号,引号里再要引号可以转义,或者改用反引号:

引号
respond "abc def"
respond "\"abc def\""
respond `{"foo":"bar"}`

地址

地址出现在站点块的第一行,Caddy 会从它推断协议、主机与端口。

地址效果
example.comHTTPS,公共可信证书
*.example.comHTTPS,通配符证书
localhostHTTPS,本地可信证书
http://HTTP,匹配所有主机
https://HTTPS,匹配所有主机
http://example.com明确的 HTTP,带 Host 匹配
example.com:443HTTPS,端口与默认一致
:8080非标准端口上的 HTTP,无 Host 匹配
localhost:8080非标准端口上的 HTTPS
127.0.0.1HTTPS,本地可信的 IP 证书

通配符 * 只能代表主机名里的一个标签:*.example.com 匹配foo.example.com,但不匹配 foo.bar.example.com。要匹配所有主机,把主机部分省掉,写https://。地址必须唯一,不能重复。地址里不能用占位符,但可以用环境变量:

环境变量
{$DOMAIN:localhost} {
	...
}

匹配器

默认情况下,指令对全部请求生效。请求匹配器用来按条件筛选请求,只有支持匹配器的指令才有匹配器标记:

匹配器
root *           /var/www   # 匹配所有请求
root /index.html /var/www   # 只匹配 /index.html
root @post       /var/www   # 只匹配名为 @post 的命名匹配器

占位符

占位符是往静态配置里注入动态值的方式,两侧用花括号包住,例如 {host}。常用的请求相关占位符有简写形式,解析时会展开:

Caddyfile展开为
{host}{http.request.host}
{method}{http.request.method}
{path}{http.request.uri.path}
{query}{http.request.uri.query}
{uri}{http.request.uri}
{header.*}{http.request.header.*}
{cookie.*}{http.request.cookie.*}
{client_ip}{http.vars.client_ip}
{file}{http.request.uri.path.file}
{dir}{http.request.uri.path.dir}

片段

用圆括号包住名字定义一个片段,然后随处 import 复用:

片段
(logging) {
	log {
		output file /var/log/caddy.log
		format json
	}
}

example.com {
	import logging
}

import 也能引入文件,还支持 glob。可以给导入传参数,在片段里用{args[0]} 引用。

注释与环境变量

注释以 # 开头,到行尾结束;# 不能出现在标记中间,这样 URI 里的 # 就不用加引号了。

环境变量
# 环境变量在解析前替换,可以展开成多个标记
{$UPSTREAMS}

# 带默认值
{$DOMAIN:localhost}

# 延迟到运行时再替换
{env.CLOUDFLARE_API_TOKEN}