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

FrankenPHP容器里127.0.0.1不是宿主机的localhost
这是最根本的认知偏差:容器有自己的网络命名空间,127.0.0.1在容器内永远指向它自己,不是你宿主机上的服务。哪怕你在宿主机执行 curl http://localhost:8080,请求也根本进不到容器里——因为 Docker 没把流量路由过去。
现象表现就是:connection refused(连接被拒绝),而不是超时或 404。说明 TCP 层连握手都没完成,压根没进程在监听那个地址+端口组合。
- 用
docker ps看到容器在运行,不代表 FrankenPHP 进程真在监听外部可访问的地址 - 日志里没报错,也不代表监听成功;它可能安静地 bind 到
127.0.0.1:8080后就等内部调用,对外“隐身” - 验证方式必须进容器查:
ss -tlnp | grep :8080或netstat -tlnp | grep :8080,看输出是不是127.0.0.1:8080(不可达)还是*:8080或0.0.0.0:8080(可达)
怎么让宿主机能访问到 FrankenPHP 容器
关键不是改 Docker 的 -p,而是让 FrankenPHP 自己监听通配地址。Docker 的端口映射只是“转发”,前提是容器里有进程在等这个端口的连接。
- 启动时加
-- -listen 0.0.0.0:8080(注意双短横--是透传给 FrankenPHP 二进制的关键) - 如果用环境变量方式,设
SERVER_HOST=0.0.0.0:8080(适用于官方镜像默认启动逻辑) - 若用
frankenphp.toml配置,确保[server]下的address = "0.0.0.0:8080",不能是"127.0.0.1:8080" -
-p 8080:8080是必要但不充分条件;只写这个,而 FrankenPHP 还在 listen127.0.0.1:8080,照样连不上
为什么 -p 127.0.0.1:8080:8080 有时也无效
这个写法本意是限制只允许宿主机访问,但它依赖 FrankenPHP 内部也在监听 0.0.0.0:8080。如果 FrankenPHP 仍固执地 bind 127.0.0.1:8080,那么即使 -p 127.0.0.1:8080:8080 把宿主机的 127.0.0.1:8080 映射进去了,容器里也没人响应。
-
-p 127.0.0.1:8080:8080只控制宿主机哪块网卡接收请求,不改变容器内监听行为 - 常见误操作:以为加了
127.0.0.1就安全,结果 FrankenPHP 没改监听地址,反而彻底失联 - 真正“只限本机”的稳妥做法是:FrankenPHP 监听
0.0.0.0:8080+-p 127.0.0.1:8080:8080+ 宿主机防火墙默认拒绝外部入向
Windows 上 PID=4 占 80/443 怎么办
当你改监听端口后仍报 bind: permission denied 或 address already in use,且 netstat -ano | findstr :80 显示 PID=4,那基本是 Windows 的 HTTP.sys 在背后占着。别杀它。
-
taskkill /f /pid 4会导致蓝屏或断网,绝对禁止 - 打开
services.msc,停用并禁用:World Wide Web Publishing Service、Web Deployment Agent Service - 更推荐一劳永逸:启动 FrankenPHP 时不碰 80/443,改用
--addr :8080或SERVER_HOST=0.0.0.0:8080,访问http://localhost:8080 - Skype、Zoom、IIS Express、MicrosoftEdgeUpdate.exe 也可能静默占 80,查
tasklist时留意这些名字
实际跑通的关键点往往藏在两处:FrankenPHP 进程是否真在 listen 0.0.0.0,以及宿主机防火墙有没有放行那个端口——前者决定“能不能连上”,后者决定“别人能不能连”。漏掉任一环节,都会卡在 connection refused。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











