需同时设置-p映射和SERVER_HOST=0.0.0.0:8000,因FrankenPHP默认只监听127.0.0.1:8000;若挂载Caddyfile则改用-p 80:80并忽略SERVER_HOST。

docker run 时 -p 参数怎么写才让 FrankenPHP 正常响应 HTTP 请求
FrankenPHP 默认监听 8000 端口(不是 80),且只绑定在 127.0.0.1:8000(即 localhost),这是它启动后无法被宿主机访问的最常见原因。
直接写 docker run -p 8080:8000 不会报错,但请求仍超时——因为 FrankenPHP 进程根本没监听 0.0.0.0:8000,只听 127.0.0.1:8000,而 Docker 容器内 127.0.0.1 指向容器自身,不对外暴露。
- 必须用
--env SERVER_HOST=0.0.0.0:8000覆盖默认绑定地址 -
-p映射本身没问题:例如-p 8080:8000表示把宿主机 8080 → 容器 8000 - 如果想用宿主机 80 端口,需 root 权限:
-p 80:8000(Linux/macOS 可行,Windows WSL2 下通常也 OK)
docker-compose.yml 中如何正确配置 FrankenPHP 的端口和环境
仅靠 ports: 不够,environment: 必须显式设置 SERVER_HOST,否则服务启动后依然不可达。
最小可用片段如下:
立即学习“PHP免费学习笔记(深入)”;
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
services:
app:
image: dunglas/frankenphp
environment:
- SERVER_HOST=0.0.0.0:8000
ports:
- "8080:8000"
volumes:
- ./public:/app/public
-
SERVER_HOST是 FrankenPHP 唯一识别的绑定控制变量,值必须是IP:PORT格式,不能省略 IP - 不要写
SERVER_PORT=8000单独变量——FrankenPHP 不认这个,它只看SERVER_HOST - 如果改了端口(比如用
8001),SERVER_HOST和ports必须同步更新,否则端口错位
为什么 curl http://localhost:8080 返回 empty reply 或 connection refused
两种典型现象对应不同根源:
-
curl: (52) Empty reply from server→ FrankenPHP 启动了,但绑定在127.0.0.1:8000,宿主机发来的请求被容器网络栈丢弃 -
curl: (7) Failed to connect to localhost port 8080: Connection refused→ 容器根本没起来,或SERVER_HOST写错(如漏了=、用了空格、IP 写成localhost)
验证方式:进容器执行 netstat -tlnp | grep :8000,看到 0.0.0.0:8000 才算对;若只显示 127.0.0.1:8000,说明 SERVER_HOST 没生效。
使用自定义 Caddyfile 时端口映射还有效吗
有效,但逻辑变了:FrankenPHP 此时退为 FastCGI 后端,Caddy 才是真正监听 HTTP 的进程。端口映射对象变成 Caddy,默认端口是 443 和 80,不再是 8000。
- 若用官方
dunglas/frankenphp镜像并挂载Caddyfile,它会自动启用 Caddy,FrankenPHP 自身不再监听 HTTP - 此时应映射
-p 80:80 -p 443:443,而不是:8000 -
SERVER_HOST在这种模式下被忽略,无需设置 - Caddyfile 中的
php_fastcgi指令仍要指向127.0.0.1:8000(容器内通信)
复杂点在于模式切换:FrankenPHP 既是独立服务器,又是 FastCGI worker,端口行为取决于是否启用 Caddy。容易被忽略的是——镜像行为随挂载文件动态变化,不看文档很容易按“HTTP 服务器”思路硬套端口映射。


















