frankenphp 启动时默认读取当前工作目录下的 caddyfile,未找到即报错退出,不回退到内置配置。

FrankenPHP 启动时默认读哪个 Caddyfile
FrankenPHP 启动时会自动查找当前工作目录下的 Caddyfile,不依赖环境变量或额外参数。没找到就报错退出,不会 fallback 到内置默认配置。这点和原生 Caddy 一致,但容易被误以为“它自己有默认配置”。
常见错误现象:caddy run 或直接运行 FrankenPHP 二进制时报 open Caddyfile: no such file or directory,其实不是安装失败,只是缺这个文件。
- 路径必须是启动命令所在目录下的
Caddyfile,不是/etc/caddy/Caddyfile,也不是容器里的/app/Caddyfile(除非你 cd 进去再跑) - Docker 场景下,要确保
Caddyfile被 COPY 或 volume 挂载到容器的工作目录(通常是/app) - 如果你用
docker-compose.yml启动,检查volumes:是否把本地Caddyfile映射对了位置,别只挂了证书目录却漏了配置文件
普通模式 vs worker 模式对应的 Caddyfile 写法差异
FrankenPHP 的 php_server 指令本身不区分模式,模式切换靠 PHP 入口脚本逻辑(比如是否调用 frankenphp_handle_request()),但 Caddyfile 里得配对的 PHP 处理行为。
普通模式(兼容传统 PHP-FPM 行为):
yourdomain.com {
php_server
}
worker 模式(要求 PHP 入口已改写、常驻):
yourdomain.com {
php_server {
root /app/public
index index.php
}
}
-
root必须显式指定,否则 worker 模式下请求可能 404(因为常驻进程不自动推导文档根) -
index建议加上,避免某些框架路由 fallback 失效 - 别在
php_server块里加fastcgi_pass—— FrankenPHP 不走 FastCGI,这是 Nginx/FPM 的写法,写了会报错
启用 HTTPS 和 HTTP/3 时 Caddyfile 怎么写才不翻车
Caddy 自动申请 Let’s Encrypt 证书的前提是:能从公网访问 80 和 443 端口,并且域名 DNS 已解析。本地开发或内网环境直接开 HTTPS 会卡在验证环节。
- 生产环境(有公网 IP + 域名):直接写域名,Caddy 自动搞定一切
example.com { php_server } - 本地开发(无域名或用
localhost):必须显式禁用 HTTPS,否则启动失败localhost:8080 { php_server }或:80 { php_server } - HTTP/3 支持无需额外开启,只要 HTTPS 正常,Caddy 默认启用;但 UDP 端口 443 必须开放(Docker 需加
- "443:443/udp") - 泛域名证书需要在 Caddyfile 里写成
*.example.com,且 Let’s Encrypt 要求该域名 DNS 记录可验证(不能只靠 hosts 文件)
修改 Caddyfile 后如何热重载生效
FrankenPHP 不支持 caddy reload,改完 Caddyfile 必须重启进程。但可以少走弯路:
- 先用
caddy validate --config Caddyfile检查语法(FrankenPHP 二进制也支持这个 flag) - Docker 场景下,别只
docker restart,要确认容器内Caddyfile确实更新了(docker exec -it frankenphp cat Caddyfile看一眼) - 如果用了
volumes:挂载,注意 Windows/macOS 宿主机编辑保存后,Linux 容器有时会因 inotify 机制延迟感知变更,建议重启容器而非依赖热重载 - 日志里出现
listening on :443或listening on :80才算真正加载成功,光看到 “starting” 不代表配置已生效
最常被忽略的一点:Caddyfile 修改后,证书缓存、TLS handshake 状态、甚至 PHP worker 进程生命周期都不会自动刷新——它们全绑定在进程启动那一刻。想彻底清空状态,就得杀掉旧进程再拉起新实例。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











