必须显式启用{frankenphp}全局块,server_name等预定义变量才被读取并映射为caddy配置变量;自定义变量如my_var默认不生效,因caddy原生不支持环境变量插值,需通过caddy adapt或envsubst预处理实现。

能,但必须显式启用 frankenphp 全局选项,且环境变量仅在 Caddyfile 解析阶段生效(不是运行时)。
为什么 SERVER_NAME 看起来能用,但自定义变量却报错
官方镜像的 Caddyfile 里注释了 SERVER_NAME、FRANKENPHP_CONFIG 等变量,容易让人误以为所有环境变量都自动可用。实际上,Caddy 默认不展开环境变量;只有在启用了 frankenphp 全局选项后,FrankenPHP 才会主动读取并注入一部分预定义变量到 Caddy 的配置上下文。你写的 {env.MY_VAR} 或 ${MY_VAR} 这类写法不会被识别——Caddy 原生不支持这种语法,除非你用 caddy adapt 预处理或外部模板工具。
常见错误现象:adapt: unknown directive 'php_server' 或 undefined variable 'MY_VAR',往往是因为漏写了 { frankenphp } 块,或误用了 shell 风格的变量引用。
frankenphp 全局块支持哪些环境变量
FrankenPHP 在解析 Caddyfile 前,会从进程环境里读取以下变量,并映射为 Caddy 内置的配置变量(注意大小写和前缀):
-
SERVER_NAME→ 映射为 Caddy 的hostname,用于匹配 server 块 -
SERVER_ROOT→ 映射为root指令的默认路径(如未显式写root) -
FRANKENPHP_CONFIG→ 用于加载额外 PHP 配置(如php.ini片段) -
CADDY_GLOBAL_OPTIONS→ 可注入全局 Caddy 配置项(如admin off)
这些变量只在 { frankenphp } 块存在时才被读取。没这个块,它们就是普通环境变量,对 Caddyfile 完全无效。
想用自定义变量?得绕过 Caddy 原生限制
Caddy 本身不提供运行时环境变量插值,所以不能直接写 log {env.LOG_LEVEL}。可行方案只有两个:
- 用
caddy adapt --pretty配合env指令(需 Caddy v2.7+),把环境变量提前注入成 JSON 配置,再交给caddy run - 用外部工具(如
envsubst)预处理 Caddyfile:先写Caddyfile.tmpl,含$MY_PORT,再执行envsubst Caddyfile - 避免硬编码:把动态值(如端口、域名)全交给
SERVER_NAME和SERVER_ROOT,这两个是 FrankenPHP 唯一保证能透传的变量
例如,你想让不同环境用不同日志路径,别试图在 Caddyfile 里写 log /var/log/$ENV/app.log —— 改用 log /var/log/frankenphp/app.log,然后靠容器卷或 systemd 环境文件控制宿主机路径。
本地调试时最容易忽略的一点
在 Docker 外本地运行 FrankenPHP 二进制时,SERVER_NAME 如果设为 localhost,Caddy 会自动启用本地证书(localhost.crt),但如果你把它设成 example.test,而宿主机的 /etc/hosts 没配解析,浏览器会直接报 DNS 错误——此时环境变量没错,错的是网络层。FrankenPHP 不验证域名是否可达,它只管把 SERVER_NAME 当作路由匹配键和证书主题用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











