最小可用caddyfile必须包含{ frankenphp }全局块,否则php_server指令报错;站点块需指定root * public/和php_server;localhost可自动https因caddy内置local ca,其他域名需公网验证。

最小可用的 Caddyfile 就是 3 行,且必须包含 { frankenphp } 全局块
不加 { frankenphp },Caddy 就不认识 FrankenPHP 的指令,php_server 会直接报错 unknown directive 'php_server'。这个块不是可选的,它是 FrankenPHP 插件的启用开关。
最小合法配置如下:
{ frankenphp }
localhost {
root * public/
php_server
}
-
root * public/:必须指定,否则静态资源(如/favicon.ico)404;*是 Caddy 2.6+ 要求的 matcher,不能省略 -
php_server:必须在站点块内,且不能带任何参数(如try_files)——最小配置下它默认就按try_files {path} /index.php行为工作 - 域名用
localhost最稳妥;若写example.com但没配 hosts 或 DNS,Caddy 启动时会卡在 ACME 检查,等超时才 fallback 到 HTTP
php_server 默认行为 vs 显式写 try_files 的区别
很多人看到文档里有 try_files {path} index.php 就照抄进最小配置,结果启动失败。这是因为 php_server 在无参数时已内置该逻辑;一旦显式加了 try_files,就必须写全路径——index.php 会被当作相对路径查找,而实际入口是 public/index.php。
正确写法(非最小,但可控):
php_server {
try_files {path} /index.php
}
-
/index.php开头的斜杠表示从root起始,即public/index.php - 漏掉
/写成index.php→ 查找当前目录下的index.php,也就是项目根目录,通常不存在 → 500 错误 - 这个显式写法只在需要自定义 fallback 顺序(比如加
404.html)时才必要
为什么 localhost 能自动 HTTPS,而其他域名不行
Caddy 对 localhost、127.0.0.1、::1 等本地地址做了特殊处理:它不走 Let’s Encrypt,而是用 internal CA 签发证书,存到 ~/.local/share/caddy/pki/authorities/local 并自动信任。所以访问 https://localhost 时浏览器提示“自签名”,点确认就能进。
- 换成
test.dev:Caddy 会尝试走公网 ACME 流程 → 需要 80 端口可访问 + DNS 可解析 → 本地开发基本失败 - 换成
test.localhost:这是 Caddy 官方认可的“伪顶级域”,同样触发 internal CA,无需改 hosts,推荐用于多项目隔离 - 想跳过 HTTPS 强制重定向?加
redir https://{host}{uri} permanent不起作用;得用tls internal显式声明
启动后打不开 Laravel 页面?先检查这三件事
最小配置跑起来不代表 Laravel 就能正常响应。常见断点不在 Caddyfile,而在环境和权限。
-
public/目录权限是否为 755?FrankenPHP 进程需能读取其中文件;若挂载自 Docker 或 WSL,可能因 UID/GID 不匹配导致 403 -
.env里APP_URL是否设为http://localhost或https://localhost?Laravel 生成的 URL(如重定向、asset)会受它影响,填错导致 JS/CSS 404 或登录后跳转空白页 - 执行
frankenphp version确认二进制版本 ≥ v1.2.0;v1.1.x 存在php_server不识别root *的 bug,必须降级用root public/
最小配置的脆弱性恰恰体现在这里:它没留容错余地,任何一个隐含依赖出问题,表现都是“页面空白”或“连接被拒绝”,而不是明确报错。调试时别只盯 Caddyfile,先确认 PHP 运行时本身是否真被加载了——看 frankenphp status 输出里的 php_version 字段。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











