Caddy

深入

模块

命名空间、标准模块清单,以及怎么把插件编译进二进制。

Caddy 的功能都以模块形式存在。模块有全局唯一的名字,按命名空间组织,编译进二进制后就能在配置里使用。

命名空间

模块名本身就是它的位置。几个常用的命名空间:

命名空间说明
http.handlers.*HTTP 处理器,请求经过的一环
http.matchers.*请求匹配器
http.encoders.*压缩编码
tls.issuance.*证书签发者
tls.get_certificate.*获取证书的方式
logging.encoders.*日志编码器
storage.*存储介质
dns.providers.*DNS 提供商,用于 DNS 挑战
caddy.listeners.*监听器包装

标准发行版包含的模块

官方构建只包含标准模块。常见的有:

节选
http.handlers.reverse_proxy
http.handlers.file_server
http.handlers.static_response
http.handlers.request_body
http.handlers.encode
http.handlers.intercept
http.matchers.host
http.matchers.path
http.matchers.path_regexp
http.matchers.method
http.matchers.header
http.matchers.expression
http.matchers.remote_ip
tls.issuance.acme
tls.issuance.internal
tls.handshake_match.sni
logging.encoders.json
logging.encoders.console
logging.writers.file
logging.writers.stderr
storage.file_system

装插件

插件是第三方的 Go 模块,需要重新编译才能用:

xcaddy
xcaddy build \
  --with github.com/caddy-dns/cloudflare \
  --with github.com/mholt/caddy-l4

或者到官方下载页勾选模块,直接下载一个已经编好的二进制。

自己写一个

写一个模块,本质上是实现一个接口、给它一个唯一的名字,再用RegisterModule 注册。模块通过 UnmarshalCaddyfile支持在 Caddyfile 里使用,通过实现 Provision 在启动时做准备工作。

my_handler.go
func init() {
	caddy.RegisterModule(MyHandler{})
}

func (MyHandler) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "http.handlers.my_handler",
		New: func() caddy.Module { return new(MyHandler) },
	}
}

写插件时请遵循宿主项目的约定:不要在模块初始化阶段做重量级工作,配置校验放到Provision 或 Validate 里。