frankenphp 默认监听127.0.0.1:8080,仅响应本地回环请求,外部访问会连接拒绝;必须显式指定-listen 0.0.0.0:8080并配合host网络模式及系统防火墙放行,才能对外暴露服务。

FrankenPHP 默认监听 127.0.0.1,外部请求根本连不上
这是最常被忽略的底层逻辑:FrankenPHP 启动时若没指定 -listen 地址,它默认绑定 127.0.0.1:8080。这个地址只响应容器内部(或宿主机 localhost)发起的连接,从外部机器、浏览器、CDN、甚至同主机其他容器访问时,TCP 连接会直接被拒绝(Connection refused),不是 404,是连不上。
现象举例:
– docker run --network host dunglas/frankenphp 启动后,curl http://localhost:8080 成功,但 curl http://宿主机IP:8080 超时
– 云服务器上用公网 IP 访问失败,但 ssh 进去本地 curl 却 OK
必须显式加 -listen 0.0.0.0:x 才能对外暴露
--network host 模式下,容器共享宿主机网络命名空间,但 FrankenPHP 进程本身仍要主动 bind 到通配地址,否则系统内核不会把外部流量路由给它。关键操作是用双短横 -- 把参数透传给 FrankenPHP 二进制:
docker run --network host dunglas/frankenphp -- -listen 0.0.0.0:8080- 想监听 80 端口:
docker run --network host --user root dunglas/frankenphp -- -listen 0.0.0.0:80(非 root 容器无法绑定特权端口) - 监听 443:
-- -listen 0.0.0.0:443,同时确保证书路径正确且/data卷持久化
注意:-listen :8080(不带 IP)等价于 -listen 127.0.0.1:8080,依然无效。
绑定 0.0.0.0 后,安全组和防火墙必须同步放行
host 模式绕过了 Docker 的 iptables 规则,但没绕过系统层防护:
- 阿里云/腾讯云安全组:必须手动添加入方向规则,开放对应端口(如 TCP 8080)
- 宿主机 firewalld:
firewall-cmd --add-port=8080/tcp --permanent && firewall-cmd --reload - ufw:
ufw allow 8080
常见误判:看到 docker ps 显示端口在运行,就以为“配置完成了”,结果卡在云平台策略层。可以用 nc -zv 宿主机IP 8080 从另一台机器测试连通性,快速定位是 FrankenPHP 绑定问题,还是外围拦截。
Caddyfile 中的协议判断可能意外失效
FrankenPHP 内置 Caddy,当它监听 0.0.0.0:80 且没配 SERVER_NAME 时,Caddy 会尝试按域名匹配 server 块。但如果你的 Caddyfile 写了:
https://example.com {
php_server
}
而实际请求走的是 http://example.com(比如 CDN 回源或本地调试),就会因协议不匹配返回 400 错误。解决办法是补一个纯 HTTP 块:
http://example.com {
php_server
}
或者更稳妥地,统一用 SERVER_NAME=:8080 关闭域名匹配逻辑,让所有请求都进同一个 HTTP server —— 这种情况下,0.0.0.0 绑定只是保证流量能进来,后续路由完全由 Caddy 配置接管。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











