docker-compose.yml中ports必须与server_name严格对齐:server_name=:80时配"80:80",server_name=:8080时配"8080:8080",https需同时配"80:80"、"443:443"和"443:443/udp",错配会导致502错误或http_host异常。

docker-compose.yml 里 ports 怎么配才生效
光写 ports: ["80:80"] 不够,必须和 SERVER_NAME 环境变量对齐,否则 FrankenPHP 内部监听的端口和容器暴露的端口错位,导致访问失败或 $_SERVER['HTTP_HOST'] 异常。
-
SERVER_NAME=:80→ 容器内 Caddy 监听:80,ports必须写"80:80" -
SERVER_NAME=:8080→ 容器内监听:8080,ports必须写"8080:8080"(不能写成"8080:80") - 如果只映射
"8080:80"但SERVER_NAME是:80,虽然请求能通,但 PHP 中看到的 Host 是localhost:8080,可能破坏 Laravel 的APP_URL或 ThinkPHP 的 URL 生成逻辑 - HTTPS 场景下,
SERVER_NAME=your-domain.com时,Caddy 默认同时监听:80(重定向)和:443(HTTPS),所以ports要同时写"80:80"和"443:443",UDP 端口也建议加上:"443:443/udp"(HTTP/3 所需)
为什么不能混用 SERVER_NAME 和 ports 的端口号
FrankenPHP 的内置 Caddy 不识别带端口的域名格式(比如 localhost:8080),它只认两种模式:your-domain.com(启用 HTTPS 自动化)或 :8080(纯 HTTP 模式)。一旦你把 SERVER_NAME 设为 :8080,它就强制在容器内监听该端口;而 Docker 的 -p 只是做端口转发,不改变服务实际绑定地址。错配后常见现象:
- 访问
http://localhost:8080返回 502 —— 因为 Caddy 在容器内监听:80,但-p 8080:80把宿主机 8080 转发到了容器 80,此时 Caddy 实际没在:8080启动监听 - 页面跳转或生成链接带
:8080后缀 ——$_SERVER['HTTP_HOST']变成localhost:8080,框架无法识别这是“标准端口”,自动补上端口 - Caddy 日志里出现
listening on :80,但你明明设了SERVER_NAME=:8080—— 说明环境变量没被正确加载(比如拼写错误、空格、引号包裹)
完整可运行的 docker-compose.yml 片段
以下是最小可用配置,适用于调试(HTTP)和生产(HTTPS)两种场景,已验证兼容 Laravel、ThinkPHP、纯 PHP 项目:
services:
php:
image: dunglas/frankenphp
environment:
- SERVER_NAME=:80 # 调试用:纯 HTTP,禁用 HTTPS
# - SERVER_NAME=example.com # 生产用:自动申请证书,需配 DNS
ports:
- "80:80"
# - "443:443"
# - "443:443/udp"
volumes:
- ./public:/app/public
- ./caddy_data:/data
- ./caddy_config:/config
注意:volumes 中的 /app/public 是 FrankenPHP 默认查找静态资源和入口文件的路径,不要改成 /app 或其他;/data 和 /config 是 Caddy 存证书和配置必需的挂载点,缺一不可。
容易被忽略的权限与路径细节
很多问题不是端口配错,而是路径或权限没对齐:
-
./public必须存在且包含index.php,FrankenPHP 不会自动创建或提示“找不到入口” - 如果项目结构是
myapp/public/,volumes必须写成- ./myapp/public:/app/public,而不是- ./myapp:/app - Docker 容器内运行用户是
www-data,确保runtime/(ThinkPHP)、storage/(Laravel)等目录对它可写,否则日志报错但端口仍“看似正常” -
SERVER_NAME值里不能有空格或引号,YAML 中直接写- SERVER_NAME=:80,不要写成- "SERVER_NAME=:80"(某些 shell 解析会出问题)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











