containerport只是端口标签,不绑定宿主机;frankenphp实际监听端口由--addr参数决定,必须与containerport一致,否则service流量无法送达。

容器内 ports 声明只是“端口标签”,不绑定宿主机
在 Kubernetes 或 Docker Compose 中写 ports 列表(比如 containerPort: 80),本质是给容器端口打个“名字+协议+数字”的标签,Kubernetes 用它做 Service 的 targetPort 匹配,Docker 则基本不用它做任何事。它不会让容器监听宿主机的 80 端口,也不会触发端口映射。
常见误操作:以为写了 containerPort: 80 就等于“暴露了 80”,结果服务根本连不上——因为 FrankenPHP 默认监听的是 :8080,不是 :80;而 containerPort 只是声明“我这个容器逻辑上提供 HTTP 服务”,并不改它的实际监听地址。
- FrankenPHP 实际监听地址由
--addr参数或 Caddyfile 中的bind控制,默认是:8080 -
containerPort数值必须和 FrankenPHP 实际监听端口一致,否则 Service 流量发过去没人收 - 若你改了
--addr :8000,就必须同步把containerPort改成8000,否则targetPort: http查不到匹配项
expose 在 Docker 中已基本失效,别依赖它
Docker 的 EXPOSE 指令(Dockerfile 里)和 expose 字段(compose.yaml 里)只是元数据,仅起文档作用:告诉别人“这个镜像默认打算用哪些端口”。它既不打开防火墙,也不做端口映射,更不会影响容器实际行为。
你写 EXPOSE 80,FrankenPHP 还是监听 :8080;你删掉所有 EXPOSE,只要 --addr :8080 存在,它照样跑。
- 现代实践中,
EXPOSE已被弃用倾向——Kubernetes 不读它,Docker Desktop 也不靠它做自动映射 - 真正起作用的是运行时参数:
--addr决定监听谁,ports列表决定 Service 怎么找它 - 如果你用
docker run -p 80:8080,映射生效是因为-p,跟EXPOSE完全无关
Kubernetes 场景下,containerPort 必须和 targetPort 对齐才能通信
Service 的 targetPort 可以是数字(如 9001)或字符串(如 fpm)。用字符串时,Kubernetes 会去容器 ports 列表里找 name: fpm 对应的 containerPort 数值;用数字则跳过匹配,直接发包到容器 IP 的该端口。
问题在于:一旦 FrankenPHP 启动参数变了监听端口(比如从 :9001 改成 :9002),而 targetPort: 9001 没同步改,流量就进不去,且无报错提示。
- 推荐始终用命名方式:
name: fpm+containerPort: 9001+targetPort: fpm - 这样改端口只需动一处(容器
ports和启动参数),Service 不用碰 - FrankenPHP 默认同时开两个端口:
80(HTTP)和9001(FPM),但绝大多数场景只用80;FPM 端口仅在极少数直连需求中才需暴露
实际监听端口不等于容器端口声明,务必检查 --addr
FrankenPHP 启动后到底监听哪个地址,只取决于你传给它的 --addr 参数(或 Caddyfile 中的 bind),和 containerPort 声明完全解耦。这是最容易被忽略的断连原因。
例如你写了:
ports: - name: http containerPort: 80 protocol: TCP
但启动命令是 frankenphp server --addr :8080,那 Service 即使把流量送到 Pod 的 80 端口,也没进程在那儿听。
- 验证方法:进容器执行
ss -tln或netstat -tln,看实际监听的是哪个:port - 正确做法:保持
--addr和containerPort一致,比如都用:80或都用:8080 - 生产环境建议显式指定
--addr :80,避免依赖默认值,也方便和containerPort对齐
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











