frankenphp容器中监听ipv6需设server_host=0.0.0.0:8000启用双栈,或server_host=[::1]:8000仅限本地ipv6回环;docker需宿主机启用ipv6、daemon.json配置ipv6:true及fixed-cidr-v6,并用-p 0.0.0.0:8000:8000映射。

FrankenPHP容器里SERVER_HOST怎么写才能监听IPv6
FrankenPHP 不识别 [::]:8000 这类 IPv6 字面量作为 SERVER_HOST 值——它只接受标准的 IP:PORT 格式,且会把 [::] 当作非法主机名直接忽略,fallback 到默认的 127.0.0.1:8000。真正生效的写法只有两种:
-
SERVER_HOST=0.0.0.0:8000:启用双栈监听(IPv4 + IPv6),前提是宿主机系统已启用 IPv6 dual-stack(Linux 默认开启,Windows 需确认) -
SERVER_HOST=[::1]:8000:仅绑定 IPv6 回环地址,适用于本地调试 IPv6 协议栈,但外部无法访问
别写 SERVER_HOST=localhost:8000 或 SERVER_HOST=:8000,前者被解析为 IPv4,后者被当作无效值静默降级。
Docker 的 -p 参数对 IPv6 有效吗
原生 Docker(20.10+)在 Linux 上支持 IPv6 端口映射,但必须满足三个条件,缺一不可:
- 宿主机已启用 IPv6:
sysctl net.ipv6.conf.all.disable_ipv6返回0 - Docker daemon 配置了 IPv6 支持:
/etc/docker/daemon.json中含"ipv6": true和有效的"fixed-cidr-v6" -
-p显式绑定到 IPv6 地址:docker run -p [::1]:8000:8000 ...(仅限回环)或-p 0.0.0.0:8000:8000(双栈,推荐)
Windows/macOS(WSL2 除外)的 Docker Desktop 默认不暴露 IPv6 接口,-p [::]:8000:8000 会静默失败,docker port 查不到映射。此时应退而求其次,用 0.0.0.0:8000:8000 + 双栈绑定,再通过反向代理(如 Caddy)做 IPv6 终结。
为什么 netstat -tlnp | grep :8000 看不到 [::]:8000
这不是 FrankenPHP 没监听,而是 Linux netstat 默认隐藏 IPv6 监听项,或你查的是错误的协议栈。真实情况分三种:
- 只看到
0.0.0.0:8000→ 表明双栈已启用,[::]:8000是隐式共享的,无需单独显示 - 只看到
[::]:8000→ 宿主机 IPv6 已禁用,或 FrankenPHP 启动时SERVER_HOST被错误覆盖为 IPv6-only - 完全看不到 →
SERVER_HOST未生效(检查是否拼错、有空格、漏等号),或容器根本没启动成功
验证命令应为:ss -tlnp | grep ':8000'(更可靠)或 lsof -iTCP -sTCP:LISTEN -P -n | grep ':8000'。若输出含 tcp6 字样,说明 IPv6 监听已就绪。
Caddyfile 里要不要写 IPv6 地址
不需要,也不应该。Caddy 的 server block 名称(如 example.com)只匹配 Host 请求头,和底层监听地址无关。Caddy 自动从 SERVER_HOST 或环境推导监听行为:
- 当
SERVER_HOST=0.0.0.0:8000时,Caddy 默认监听[::]:8000和0.0.0.0:8000(双栈) - 若你挂载了自定义
Caddyfile,其中:8000或*:8000就足够,[::]:8000是冗余且可能报错的语法 - 想强制只走 IPv6?改用
SERVER_HOST=[::1]:8000+Caddyfile中写[::1]:8000,但仅限测试,生产勿用
真正影响 IPv6 可达性的,从来不是 Caddyfile 写法,而是宿主机网络配置、Docker 的 IPv6 支持状态、以及防火墙是否放行 ip6tables 规则——这三处漏掉任意一个,curl -g http://[2001:db8::1]:8000 都会超时。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











