docker compose 的 ports 字段不支持环境变量展开,${http_port} 会被当作字面量导致错误;正确做法是用 .env 文件定义变量,并在 ports 中写 - "${http_port:-80}:80",同时通过 environment 注入变量供 caddyfile 动态引用。

docker-compose.yml 里怎么用环境变量定义端口映射
FrankenPHP 的 Docker Compose 配置不支持直接在 ports 字段里写 ${HTTP_PORT} 这类变量——Docker 引擎本身就不解析端口字段中的变量,会静默忽略或报错 invalid port specification。
必须把端口声明“移出”ports,改用 environment + 启动时参数或 Caddyfile 动态绑定的方式间接控制。常见做法是:让 FrankenPHP 启动后由 Caddy 主动监听环境变量指定的端口,而不是靠 Compose 做端口映射。
- 在
docker-compose.yml中通过environment注入变量,例如:HTTP_PORT=8080、HTTPS_PORT=8443 - 在容器内,Caddy 会读取这些变量(需确保 Caddyfile 使用
import或模板语法引用);FrankenPHP 自身不消费这些变量,它只响应 Caddy 转发来的请求 - 实际暴露给宿主机的端口仍需硬编码在
ports下,但可配合.env文件统一管理,例如:ports: - "${HTTP_PORT:-80}:80"—— 注意这里左边是宿主机端口,右边是容器内固定端口(Caddy 默认监听 80/443)
为什么不能直接 ports: - "${HTTP_PORT}:80"
因为 Docker Compose 的端口字段不经过变量展开,${HTTP_PORT} 会被当成字面量字符串处理,导致启动失败或映射到错误端口(比如映射成 "${HTTP_PORT}":80,Docker 解析为非法端口名)。
你看到的“生效”,往往是误以为变量起作用了,其实只是 Compose 把未定义变量当空字符串处理,最终变成 :80(等价于随机端口),或者因格式错误直接退出。
- 验证方式:运行
docker-compose config,查看输出中ports是否已展开为数字(如- "8080:80");若仍是${...},说明没生效 - 真正支持变量展开的字段只有
environment、image、volumes等少数几个,ports不在其中 - 绕过限制的唯一可靠方式是:用
.env文件定义变量,在ports中写- "${HTTP_PORT:-80}:80",并确保该文件存在且被docker-compose正确加载(默认会读当前目录下的.env)
Caddyfile 怎么读取环境变量动态监听端口
FrankenPHP 内置的 Caddy 服务器支持环境变量插值,但仅限于 Caddyfile 内部,且需启用 http.reverse_proxy 或 tls 等模块时显式调用。
例如,在 Caddyfile 中写:
http://:${HTTP_PORT} {
reverse_proxy localhost:8000
}
这要求容器启动时已注入 HTTP_PORT,且 Caddy 启动前该变量已存在于进程环境中(Docker 的 environment: 或 env_file: 可达成)。
- 注意:Caddy 的变量插值只在配置加载时做一次,不能热更新;改了环境变量要重启容器
- 如果同时用自动 HTTPS,
https://:${HTTPS_PORT}必须配对开启 TLS,并确保证书路径和域名匹配,否则 Caddy 拒绝加载 - 不要混用:一边在
ports映射8443:443,一边在 Caddyfile 写https://:8443—— 这会导致端口冲突或监听失败
容易被忽略的权限与调试陷阱
即使变量展开成功、Caddyfile 也写了动态端口,仍可能因底层权限或路径问题卡住。
- Caddy 默认以非 root 用户(如
www-data)运行,无法监听1024以下端口;若设HTTP_PORT=80,必须加cap_add: - NET_BIND_SERVICE或改用8080等高位端口 - 环境变量名大小写敏感:
http_port和HTTP_PORT是两个变量;Caddyfile 里写的${HTTP_PORT}必须和environment:中定义的完全一致 - Docker 的
env_file:加载顺序优先级高于environment:,若两者定义同名变量,env_file里的值会覆盖后者;调试时先跑docker-compose exec php env | grep HTTP_PORT确认实际值
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











