最准确验证frankenphp容器监听状态的方法是ss -tlnp | grep ':8080':有0.0.0.0:8080且含frankenphp进程即成功暴露;仅127.0.0.1:8080则外部不可达;无输出说明bind失败,需检查document-root等前置配置。

进容器后用 ss -tlnp 查监听状态最直接
FrankenPHP 容器启动后,光看日志里 “Starting on http://:8080” 不代表真在监听——可能因权限、配置或路径问题静默失败。ss -tlnp 是 Linux/WSL 容器内最准的验证命令,它不依赖进程名模糊匹配,直接读取内核 socket 表。
执行前需确保有 root 权限(docker exec -u 0 或容器以 root 运行),否则 -p 参数看不到 PID 和进程名:
-
sudo ss -tlnp | grep ':8080'→ 若输出含frankenphp且0.0.0.0:8080(不是127.0.0.1:8080),说明已对外暴露 - 若只看到
127.0.0.1:8080,外部 curl 会超时,得检查是否误配了--addr 127.0.0.1:8080 - 无输出?说明 FrankenPHP 没成功 bind,不是端口被占,而是启动卡在前置步骤(如 document-root 不存在)
curl -v http://localhost:8080/health 是最终验活手段
监听存在 ≠ 服务可用。/health 是 FrankenPHP 内置健康检查端点(无需额外配置),能绕过路由、中间件和静态文件逻辑,直通运行时。
在容器内执行该命令,关键看三处:
- HTTP 状态码必须是
200,500或connection refused都算失败 - 响应头中应含
Server: FrankenPHP,排除被 nginx/php-fpm 代理劫持 - 若返回
404,说明 FrankenPHP 起来了,但没挂载正确 document-root(比如漏了--document-root public)
非 root 用户运行时,ss 可能不显示进程名
FrankenPHP 官方镜像(如 dunglas/frankenphp)默认以 www-data 启动,此时 sudo ss -tlnp 仍能查端口,但 -p 列为空或报 permission denied —— 这是预期行为,不影响判断监听本身。
这时改用无权限依赖的方式确认:
-
ss -tln | grep ':8080'→ 看是否有0.0.0.0:8080行,有即表示 bind 成功 - 从宿主机
curl -v http://localhost:8080/→ 若通,说明监听 + 网络映射都 OK;若不通,再回头查 Docker-p是否写错(如-p 8080:80就会错) - 注意:非 root 用户无法监听
:80,如果SERVER_NAME=:80但容器以 www-data 运行,ss -tln根本不会出现:80行,必须换端口或加 cap
别信 lsof 在容器里的输出
多数 FrankenPHP 容器镜像没装 lsof,强行 apt install lsof 会增大镜像体积,且在 Alpine 基础镜像里甚至不可用。更关键的是:lsof -i :8080 在容器内常因 chroot 或 pid namespace 隔离而漏掉进程,不如 ss 直接读内核。
如果非要对比工具,优先级是:
- Linux/WSL 容器:
ss -tlnp(有权限)或ss -tln(无权限) - macOS 宿主机查容器端口占用:
lsof -P -n -i :8080(查宿主机侧映射) - Windows WSL2:
netstat -ano | findstr :8080(查 WSL2 内部),再用 PowerShell 查 Windows 侧是否被 HTTP.sys 占:80
监听状态这事,内核说了才算数,日志和进程列表只是参考。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











