Caddy 报 unrecognized directive: dns:先把 tls 放进正确站点块
Caddyfile 转换报 unrecognized directive: dns,先核对站点、tls 与 dns 子块层级,再检查运行构建的提供商模块和证书验证阶段。
Caddy 启动时在 adapting config using caddyfile 阶段失败,随后提示 unrecognized directive: dns。Caddyfile 最前面写了 tls 邮箱地址 { ... },域名站点却放在后面时,先检查配置层级。解析器可能把 tls 和邮箱读成站点地址,随后把 dns 当作普通站点指令。
本文针对 Caddy 2 的 HTTP Caddyfile,且错误发生在配置转换阶段。DNS API 权限、TXT 传播和证书签发还没有因此得到验证;不要仅凭这个报错就更换 Cloudflare 令牌或关闭 TLS。
域名在站点块外,tls 和 dns 各有自己的层级
下面是使用 Cloudflare DNS 验证的结构示例。域名、邮箱、上游地址及环境变量名均需按实际部署调整:
wiki.example.com {
tls admin@example.com {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
reverse_proxy 192.0.2.10:80
}
站点地址 wiki.example.com 后打开站点块,tls 在其中,dns 再放入 tls 的子块。把 dns 移到 reverse_proxy 旁边,或者只多加一对外层花括号,都不会得到这个结构。
开括号应放在对应行末尾,前面留空格;闭括号单独一行。缩进帮助阅读,但实际层级由花括号确定。多个站点要分别界定块,不能靠空行结束前一个站点。
Caddyfile 可以在最前面有一个无站点名称的全局选项块,不过它只接收全局选项。全局的 email 与站点 tls 指令也不是同一个层级。这里修正的是 tls 下面的 DNS 配置位置,不能据此推断所有版本都不存在名称为 dns 的全局选项。
层级正确后,再核对运行二进制中的模块
使用与服务相同的二进制或容器查看模块:
caddy version
caddy list-modules
使用上述 Cloudflare 配置时,应有 dns.providers.cloudflare。DNS 提供商模块需要包含在 Caddy 构建中,写上名称不会自动安装。宿主机另一个 Caddy 有模块,也不能证明实际容器镜像有。
如果修正层级后变成模块未注册一类错误,检查镜像或构建的模块清单,再按现有版本管理流程准备包含所需模块的构建。保留旧镜像和配置,确认其他已有模块也被保留;不要为了加插件直接替换成版本和能力未知的二进制。
当前 Cloudflare 模块可从环境占位符读取 API Token,要求管理目标区域所需的 Zone Read 与 DNS Edit 权限。令牌必须对实际 Caddy 进程可见;交互终端设置过变量,不等于服务管理器或容器启动时也取得了它。核对时避免输出令牌本身。
转换成功与能够签发证书是不同检查
在受控环境中,可以先转换准备好的配置:
caddy adapt --config /etc/caddy/Caddyfile --adapter caddyfile
它用于发现层级和适配问题,不应用配置。输出的 JSON 可能含展开后的敏感值,只在受控终端查看,不公开完整结果。
模块加载和 provision 阶段仍可能出错。caddy validate 比仅转换更深入,但会实际 provision 模块;某些模块会获取独占资源,运行中的实例可能影响校验。按当前部署流程选择校验方式,不把它当成完全无副作用的文本检查。
对已运行服务,保存原配置后按现有管理方式重载。使用 caddy reload 需要可用的管理端点;不要因端点不可用临时停止全部站点。失败时查看具体阶段:语法错误、模块缺失、API 认证失败、DNS 传播或上游不可达分别处理,不通过关掉验证来掩盖后续错误。
成功标准是配置被实际运行实例接受,所需证书签发或加载正常,目标域名 HTTPS 访问及代理功能正常。回退时恢复原配置和必要的原镜像,保留证书存储;仅修正括号不能保证证书和后端同时恢复。


