核心是确保web服务器用户(如www、www-data)对storage/和bootstrap/cache/拥有读写权限,执行sudo chown -r www:www storage/ bootstrap/cache/与sudo chmod -r 755,重建public/storage软链接,排除selinux拦截,并显式指定store('path', 'public')磁盘。

解决 Laravel 10 的 storage 权限报错,核心是确保 Web 服务器进程(如 www-data、nginx 或宝塔的 www)对 storage/ 和 bootstrap/cache/ 目录拥有稳定、安全的读写权限,同时排除 SELinux、符号链接、磁盘配置等常见干扰项。
确认并修正目录所有权和基础权限
权限错误最常见原因是 Web 用户无权写入。先查清当前 Web 服务用户:
- Ubuntu/Debian + Nginx/Apache:通常是
www-data - CentOS/RHEL + Apache:默认为
apache;Nginx 则多为nginx - 宝塔面板:几乎总是
www(不是www-data),务必进 PHP 配置文件确认user =和group =值
进入项目根目录后执行:
sudo chown -R www:www storage/ bootstrap/cache/ sudo chmod -R 755 storage/ bootstrap/cache/
755 是生产环境推荐值:所有者可读写执行,组和其他人可读可执行——足够安全且满足 Laravel 运行所需。切勿用 777。
重建 public/storage 软链接
上传文件能存进去但 URL 访问 404,大概率是软链接损坏或缺失。
- 检查是否存在:
ls -l public/storage—— 正常应显示lrwxrwxrwx开头的链接行 - 若不存在或指向错误,先删掉:
rm -f public/storage - 重新生成:
php artisan storage:link - 验证结果:
ls -ld public/storage应为链接,且目标路径是../storage/app/public
注意:如果服务器 public 目录实际叫 public_html(如共享主机),需先修改 config/filesystems.php 中的 links 数组,再运行命令。
排查 SELinux 或安全模块拦截
在 CentOS、Rocky 或 AlmaLinux 上,即使权限看着全对,仍可能因 SELinux 拦截导致静默失败。
- 快速检测:
sudo sestatus—— 若输出enforcing,就是它在作怪 - 临时测试(不推荐长期使用):
sudo setsebool -P httpd_read_user_content 1 - 永久修复(推荐):
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/your-app/storage(/.*)?"sudo restorecon -Rv /var/www/your-app/storage
别用 setenforce 0 关闭 SELinux,那只是掩盖问题,不是解决问题。
验证上传逻辑是否命中正确磁盘
很多“上传失败”其实是因为文件被存到了 local 磁盘(storage/app/),而非 public 磁盘(storage/app/public/),导致无法通过 /storage/xxx 访问。
- 显式指定磁盘:
$request->file('photo')->store('photos', 'public') - 检查配置:
config/filesystems.php中'public'磁盘的'driver'必须是local,'root'必须指向storage_path('app/public') - 手动验证文件是否存在:
Storage::disk('public')->exists('photos/test.jpg')
别依赖默认 store(),Laravel 10 默认走的是 config('filesystems.default'),通常为 local,它不公开。











