laravel静态资源404主因是frankenphp未正确服务public/目录:需确保caddyfile中root与php_server路径均精准指向public/,且项目结构合规、fileinfo扩展启用、curl验证响应头确认静态文件由caddy直供。

静态资源返回 404,基本可以确定不是 Laravel 或 Symfony 的路由没匹配上,而是 FrankenPHP 根本没把请求当作静态文件处理——它直接交给了 PHP,而 PHP 入口(index.php)又不负责返回 js/app.js 这类文件,结果就是 404。
确认 Caddyfile 中 root 和 php_server 路径是否一致且正确
FrankenPHP 依赖 Caddyfile 明确声明 Web 根目录,并让 php_server 知道从哪开始找 PHP 文件和静态资源。两者必须都指向 public/,且路径写法要严格匹配实际挂载结构:
-
root public/:表示 Web 根是当前目录下的public/子目录(不是./public,也不是/app/public) -
php_server { try_files {path} index.php }:其中{path}是相对于root的路径,所以它会先查public/js/app.js - 如果
root写成root /app/public(绝对路径),但容器里挂载的是-v $PWD:/app,那 Caddy 实际找不到/app/public/js/app.js,因为文件在/app/public/public/js/app.js
检查项目结构与挂载方式是否合规
FrankenPHP 官方镜像和二进制默认以 public/ 为 Web 入口,这点不能妥协:
- 运行
ls -l public/,确认index.php、css/、js/都存在 - Docker 挂载必须是
-v $PWD:/app,而不是-v $PWD/public:/app——后者会让root public/实际变成/app/public/,多出一层嵌套 - 独立二进制运行时,
Caddyfile必须放在 Laravel/Symfony 项目根目录(即composer.json所在处),不能放在public/里
验证 fileinfo 扩展是否启用
fileinfo 缺失会导致 Caddy 无法正确识别 MIME 类型,进而跳过静态服务逻辑,直接 fallback 到 index.php:
- 执行
frankenphp php-cli -m | grep fileinfo(二进制)或docker exec -it your-container frankenphp php-cli -m | grep fileinfo(Docker) - 若无输出,说明未启用;Docker 用户可在构建镜像时加
RUN install-php-extensions fileinfo - 二进制用户需下载带该扩展的版本,或手动编译;否则
hello.txt可能被当成text/html返回,甚至触发 PHP 解析
用 curl -I 直接验证静态路径是否真由 Caddy 服务
别只看页面能不能打开,要确认响应头是否干净:
- 放一个
public/hello.txt,内容为static ok - 执行
curl -I http://localhost:8000/hello.txt,检查:
– 状态码是200(不是500或404)
–Content-Type是text/plain; charset=utf-8(不是text/html)
– 响应头里没有X-Powered-By或任何 PHP 相关字段 - 再试一个不存在的路径,如
curl -I http://localhost:8000/missing.css,应返回404且响应体为空 —— 如果返回了 PHP 错误堆栈,说明php_server配得太宽,所有路径都被 fallback 了
最容易被忽略的是路径层级错位:你以为挂载对了,其实 root public/ 在容器里展开后变成了 /app/public/public/;还有就是 fileinfo 缺失导致 MIME 推断失败,Caddy 放弃静态处理——这两点不排查,光调 try_files 顺序没用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











