frankenphp容器内监听端口由server_name环境变量决定:设server_name=:80则监听:80,设=:8080则监听:8080;必须同步用-p映射对应宿主机端口,且server_name优先级高于frankenphp.toml和caddyfile配置。

FrankenPHP 容器内监听端口由 SERVER_NAME 决定
FrankenPHP 容器不通过 --port 或配置文件改监听端口,而是靠 SERVER_NAME 环境变量驱动内置 Caddy 的监听行为。它不是“设置端口”,而是用这个值告诉 Caddy:“只监听这个地址,别管域名、别申请证书”。
-
SERVER_NAME=:80→ 容器内监听:80(HTTP) -
SERVER_NAME=:8080→ 容器内监听:8080 -
SERVER_NAME=localhost或example.com→ 触发 HTTPS 自动流程,默认监听:443和:80(跳转用) -
SERVER_NAME值里不能带协议(如http://)或路径,只接受:端口或纯域名格式
docker run 时必须同步映射对应宿主机端口
光设 SERVER_NAME=:8080 不够,Docker 默认不会把容器 :8080 暴露给宿主机。映射错会导致 curl 能连上但返回空、超时,或 $_SERVER['HTTP_HOST'] 异常。
- 正确:
docker run -e SERVER_NAME=:8080 -p 8080:8080 dunglas/frankenphp - 错误:
SERVER_NAME=:80却只写-p 8080:80—— 容器内监听:80,宿主机 8080 转发过去,虽然能通,但 PHP 中看到的 Host 是localhost:8080,可能破坏 Laravel 的APP_URL或 Symfony 的 URL 生成逻辑 - 若用
-p 8080:80映射,SERVER_NAME必须是:80,否则 Caddy 在容器内根本没监听那个端口
用 frankenphp.toml 配置时,address 优先级低于 SERVER_NAME
即使挂载了自定义 frankenphp.toml 并写了 [server] address = "127.0.0.1:8001",只要设置了 SERVER_NAME,FrankenPHP 就会忽略 TOML 里的 address,强制按 SERVER_NAME 解析监听地址。
- 想用 TOML 控制端口?必须不设
SERVER_NAME环境变量 -
SERVER_NAME=:8080时,TOML 中的tls.address会被自动禁用(因为 HTTP 模式不启用 TLS) - 若同时挂载 Caddyfile,它也会被
SERVER_NAME覆盖——FrankenPHP 只启一个 server 块,这是设计行为,不是 bug
验证监听是否生效,别只看容器日志
容器启动后输出 Starting FrankenPHP server on http://localhost:8080 并不代表它真在监听那个端口。macOS/Linux 上应直接查容器内进程绑定状态:
- 进容器执行:
ss -tln | grep ':8080'或netstat -tln | grep ':8080' - 宿主机查(需容器运行中):
docker exec -it <container-id> ss -tln | grep ':8080'</container-id> - 如果没输出,说明
SERVER_NAME值无效或拼写错误(比如多了空格、用了http://localhost:8080) - curl 测试前先确认:
curl -v http://localhost:8080(宿主机)或curl -v http://127.0.0.1:8080(容器内)
SERVER_NAME,映射对 -p。其余配置项(TOML、Caddyfile、命令行参数)在有 SERVER_NAME 时基本失效,这点容易被忽略。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











