第一步是检查public/storage软链接是否存在且指向正确:执行ls -la public/storage,若显示storage -> ../storage/app/public则链接有效;若提示no such file or directory则需运行php artisan storage:link重建;若显示broken symbolic link则说明目标路径缺失或权限异常。

public/storage 软链接是否存在且指向正确
直接检查软链接是否真实存在、目标路径是否可解析,是第一步。别只看有没有 public/storage 这个目录名,它可能是普通文件夹而非软链接。
执行命令:ls -la public/storage
- 若输出类似
storage -> ../storage/app/public,说明链接存在且为相对路径(推荐) - 若显示
public/storage: No such file or directory,说明链接根本没建,需立刻运行php artisan storage:link - 若显示
storage: broken symbolic link to ../storage/app/public,说明目标路径被移动、删除或权限异常,storage/app/public本身可能已不存在
storage/app/public 目录是否可被 Web 用户读取
软链接存在 ≠ 能访问。Linux 下“进入目录”需要执行(x)权限,“读取文件”需要读(r)权限,且属主属组必须匹配 Web 服务器实际用户(如 www-data、nginx 或 www)。
先确认 Web 用户是谁:
- Nginx 环境:查
ps aux | grep nginx,看 worker 进程的 USER 列 - Apache 环境:查
httpd.conf或apache2.conf中的User/Group配置
再检查路径权限:
-
ls -ld storage→ 看根目录是否有 x 权限(否则进不去) -
ls -ld storage/app→ 同样需 x 权限 -
ls -ld storage/app/public→ 必须有 r-x(至少 755),且属主属组与 Web 用户一致
不匹配就改:例如 Web 用户是 www-data,则运行 sudo chown -R www-data:www-data storage/app/public,再补权限 sudo chmod -R 755 storage/app/public。
Web 服务器能否真正读取到某个 CSS 或图片文件
别依赖浏览器报错或 curl 测试——它们走的是 HTTP 协议栈,中间可能被 Nginx/Apache 规则拦截。最准的方式是**以 Web 用户身份直读文件**。
例如:
- 运行
sudo -u www-data cat storage/app/public/css/app.css - 若报
Permission denied,说明某一级目录缺 x 权限,或文件本身缺 r 权限 - 用
namei -l storage/app/public/css/app.css查每层权限和属主,快速定位卡在哪一级(比如storage目录属主是 root,但权限是 750,www-data 就进不去)
注意:Windows + Homestead/Vagrant 场景下,php artisan storage:link 在 Windows 上生成的 mklink 是绝对路径,Homestead 内无法解析。此时必须在虚拟机内手动重建相对链接:ln -s ../storage/app/public public/storage。
Nginx/Apache 是否放行了 /storage/ 下的静态资源
即使软链接和权限全对,Nginx 也可能因配置限制导致 404。典型表现是:能访问 /storage/test.txt,但访问 /storage/image.jpg 返回 404。
检查 Nginx 配置中是否有类似这样的 location 块:
location ~ \.(js|css|png|jpg|gif|svg)$ {
try_files $uri =404;
}
问题就在这里:$uri 指向的是 public/storage/xxx.jpg,但该路径是软链接,而 try_files 默认不跟随符号链接(除非显式开启 disable_symlinks off;)。更稳妥的做法是显式声明 /storage/ 路径由 alias 处理:
location /storage/ {
alias /path/to/your/project/storage/app/public/;
expires 1y;
add_header Cache-Control "public, immutable";
}
Apache 用户请确认 Options FollowSymLinks 已启用,且 .htaccess 未覆盖规则。
软链接本身很轻量,但它的有效性完全依赖三件事:链接存在、目标可达、Web 服务放行。漏掉任意一环,/storage/xxx 就只是 URL,不是资源。











