根本原因是php进程对storage目录无读写执行权限,需确保web与cli用户属主一致、目录具备x权限、文件具备r/w权限,并通过g+s使子目录自动继承组权限。

Laravel 10 使用本地驱动(local)存储文件时,在 Linux 系统上遇到“Permission denied”错误,根本原因不是 Storage 配置写错了,而是 PHP 进程(Web 或 CLI)对 storage/ 及其子目录没有正确的读、写、执行权限。关键在三点:属主对齐、目录可进入(x 权限)、组协同读写。
确认 Web 服务器与 CLI 的实际运行用户
Web 请求和命令行操作由不同用户触发,必须分别对待:
- 查 Web 用户:运行
ps aux | grep -E '(php-fpm|nginx|apache)' | grep -v grep,看 user 列(如www-data、nginx或www) - 查 CLI 用户:终端中运行
whoami和id -gn,确认当前 shell 用户及主组 - 常见错配:Web 用
www-data,但你用root或普通用户执行过php artisan,导致storage/下部分文件属主为root,Web 进程就无法写入
重设 storage 和 bootstrap/cache 所有权
这两个目录必须同时归属 Web 用户(用于运行时)和 CLI 用户(用于开发维护)。推荐统一用 Web 用户作为属主,再把当前开发用户加入该组:
- 先查 Web 用户组名(通常与用户名相同),例如
www-data - 把当前用户加入该组:
sudo usermod -aG www-data $USER,然后退出重登生效 - 递归修改属主:
sudo chown -R www-data:www-data storage/ bootstrap/cache/ - 特别注意:
bootstrap/cache/缺失或权限不对会导致 Laravel 启动失败、空白页、连日志都写不出来
设置合理权限并启用组继承
权限不是越宽越好,755 + 组写(g+s)才是生产安全的组合:
- 所有目录设为
755(所有者 rwx,组和其他人 rx):find storage bootstrap/cache -type d -exec chmod 755 {} \; - 所有日志、缓存文件设为
644:find storage/logs storage/framework/cache -type f -exec chmod 644 {} \; - 给
storage/和bootstrap/cache/加上 setgid:sudo chmod g+s storage/ bootstrap/cache/,确保 Laravel 自动创建的子目录(如storage/framework/views)自动继承www-data组,避免后续手动 chmod
验证 public/storage 软链接与 Web 可读性
如果前端资源(CSS/JS/上传图片)返回 403,问题常出在这里:
- 运行
ls -la public/storage,确认它指向../storage/app/public - 重建链接(如果损坏):
php artisan storage:link - 模拟 Web 用户读取:
sudo -u www-data ls -l storage/app/public/,若报错,说明storage/app/public及其父级缺少组读/执行权限 - 补全组权限:
sudo chmod -R g+rx storage/app/public
不复杂但容易忽略











