server_name=:80是唯一有效的禁用https方式,它强制caddy监听:80、禁用域名匹配与acme证书申请,实现纯http模式;需配合docker -p端口映射且不可混搭,caddyfile中域名配置将被忽略。

SERVER_NAME=:80 是唯一有效的禁用 HTTPS 方式
FrankenPHP 容器里没有“关闭 HTTPS 开关”,它的 HTTPS 行为完全由 Caddy 的监听地址推导而来。写 SERVER_NAME=your-domain.com 就会触发 ACME 自动申请、强制跳转 HTTPS;而只有 SERVER_NAME=:80 才能让 Caddy 放弃域名匹配逻辑,只监听 :80 并禁用 TLS 处理路径。
常见错误写法包括:
-
SERVER_NAME=localhost:8080—— Caddy 不识别带端口的主机名,直接 fallback 到默认行为(通常是 HTTPS) -
SERVER_NAME=127.0.0.1或SERVER_NAME=0.0.0.0—— 仍被当作域名处理,ACME 流程照常启动 - 漏掉冒号,写成
SERVER_NAME=80—— 环境变量无效,FrankenPHP 忽略,走默认 HTTPS
必须同步做端口映射,否则外部连不上
光设 SERVER_NAME=:80 不够。FrankenPHP 在容器内监听 :80,但 Docker 默认不暴露任何端口。你得显式用 -p 把宿主机端口和容器端口对齐:
- 想用宿主机 80 端口 → 启动命令加
-p 80:80 - 想用宿主机 8080 端口 → 必须同时改两处:
SERVER_NAME=:8080+-p 8080:8080 - 禁止混搭:
SERVER_NAME=:80却只-p 8080:80—— 虽然能通,但$_SERVER['HTTP_HOST']变成localhost:8080,Laravel 的APP_URL生成可能出错
Caddyfile 和 SERVER_NAME 冲突时谁生效?
如果你挂载了自定义 Caddyfile,里面写了 example.com { } 这类域名块,但环境变量是 SERVER_NAME=:80,最终生效的是后者。FrankenPHP 会忽略 Caddyfile 中所有域名配置,只启用一个 :80 的纯 HTTP server。这不是 bug,是设计行为。
所以别在 Caddyfile 里写 tls、redir 或 https:// 相关指令——它们全被跳过。真正起作用的只有 SERVER_NAME 环境变量的值。
验证是否真跑在 HTTP 模式下
别只看浏览器地址栏是不是 http://,有些缓存或中间件会偷偷重定向。实测方法更可靠:
- 用
curl -I http://localhost:80(注意是http://,不是https://),响应头首行应为HTTP/1.1 200 OK;如果返回301 Moved Permanently到https://,说明SERVER_NAME没生效 - 检查容器日志:启动时若出现
autosaved config或enabling automatic HTTPS字样,说明仍在走 HTTPS 流程 - 删掉
caddy_data卷再试一次 —— 旧证书缓存可能导致行为残留
最容易被忽略的是 HSTS 缓存:浏览器记住了之前 HTTPS 响应里的 Strict-Transport-Security 头,即使服务端已切回 HTTP,它仍会强制跳转。换无痕窗口或清空 HSTS 记录再测。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











