必须将网站根目录设为public/,伪静态规则必须用Nginx版try_files $uri $uri/ /index.php?$query_string;,否则所有路由404;需清空open_basedir并关闭防跨站攻击,否则storage和bootstrap/cache写失败。

必须把网站根目录设为 public/,伪静态规则必须用 Nginx 版本的 try_files $uri $uri/ /index.php?$query_string;,否则所有路由 404,连首页都打不开。
网站根目录必须指向 public/,不是项目根目录
宝塔默认把根目录设成项目整体(比如 /www/wwwroot/myapp),这会让 .env、app/、routes/ 全部暴露在 Web 可访问路径下,极不安全,且 index.php 找不到自动加载器,直接报错。
正确做法是:
- 进「网站」→ 选你的站点 → 「设置」→ 「网站目录」→ 把「网站目录」路径改为
/www/wwwroot/myapp/public - 改完立刻点「保存」,否则 Nginx 配置不会重载
- 验证是否生效:访问
http://your-domain/.env必须返回 404 或 403;访问http://your-domain应能显示 Laravel 欢迎页 - 别手误填成
/www/wwwroot/myapp/public/index.php—— 根目录只到目录层,不是文件
伪静态规则必须用 Nginx 的 try_files,不能套 Apache 规则
宝塔「伪静态」选项卡里选「Laravel 5」是最快方式,它生成的就是标准 Nginx 规则。但很多人手动粘贴时抄错格式,或混用 Apache 的 .htaccess 写法,结果路由全挂。
关键点:
- 规则必须放在
location / { ... }块内,不是全局或server块顶层 -
try_files $uri $uri/ /index.php?$query_string;中的空格和符号一个都不能少(尤其$query_string前面是?不是&) - 如果用了 Vue Router history 模式或自定义 API 前缀(如
/api/),需额外加location ^~ /api/ { ... }块,避免静态资源被错误转发 - 绝对不要往
public/目录丢.htaccess文件 —— Nginx 完全不读这个
open_basedir 必须清空,否则 storage 和 bootstrap/cache 写失败
即使你把目录权限设成 775,只要宝塔「防跨站攻击」开着,或 open_basedir 还残留值,PHP-FPM 就会拒绝写入 storage/logs 或生成缓存文件,导致 php artisan config:cache 失败、日志空白、队列无法启动。
操作步骤:
- 进「网站」→ 你的站点 → 「PHP 设置」→ 找到「open_basedir」输入框,把它清空(留空,不是填
none) - 同时关闭「防跨站攻击」开关(有些版本只关开关不够,必须清空 open_basedir)
- 检查
/www/wwwroot/myapp/.user.ini是否存在 —— 如果有,它可能继承了父级限制,需进入public/目录新建一个同名文件,内容只写:open_basedir=/www/wwwroot/myapp/:/tmp/:/proc/ - 改完后执行
kill -USR2 $(cat /www/server/php/81/var/run/php-fpm.pid)(路径按你实际 PHP 版本调整)重载配置
最常被忽略的是:改完伪静态和根目录后没点「保存」,或者 open_basedir 看似关了但 .user.ini 还在作祟。这两个地方一错,Nginx 日志里就只有模糊的 500 或空响应,根本看不到具体哪行 PHP 报错。


















