Ubuntu下Laravel调用Artisan::call('storage:link')报symlink权限错误如何解决
问题原因及解决方法
错误根因
- EC2 Ubuntu环境下,Web服务(Nginx/Apache)默认以
www-data用户身份运行PHP代码,你代码中调用Artisan::call()也会继承该用户的权限 - 你的Laravel项目
public/目录的所有者/所属组不是www-data,或者没有给www-data开放写入权限,创建软链接时就会触发symlink(): Permission denied报错 - 终端加sudo执行时是root权限,不受目录权限限制,因此可以正常执行
具体配置方案
方案1:调整项目目录权限(最推荐,无安全隐患)
终端执行一次权限配置后,后续代码就能正常调用命令,不需要再操作终端:
注意把下方的
/path/to/your/laravel/project替换成你实际的项目根目录路径
# 把项目所有文件的所有者改为www-data用户和用户组 sudo chown -R www-data:www-data /path/to/your/laravel/project # 给项目目录和文件设置基础权限 sudo find /path/to/your/laravel/project -type d -exec chmod 755 {} \; sudo find /path/to/your/laravel/project -type f -exec chmod 644 {} \; # 给storage和bootstrap/cache目录开放写权限 sudo chmod -R 775 /path/to/your/laravel/project/storage /path/to/your/laravel/project/bootstrap/cache
配置完成后,直接在控制器中调用Artisan::call('storage:link')即可正常执行。
方案2:手动预创建软链接(适合不需要动态创建链接的场景)
如果你不需要在代码中动态生成链接,直接在终端执行一次sudo php artisan storage:link创建好软链接后,只要不删除public/storage链接,后续不需要重复执行该命令,也不会再触发权限错误。
方案3:配置sudo免密执行该命令(不推荐,存在安全风险)
如果确实有动态执行的特殊需求,可以配置sudoers让www-data用户执行指定命令时不需要输入密码:
- 终端执行
sudo visudo打开sudo配置文件 - 在文件末尾添加一行:
www-data ALL=(ALL) NOPASSWD: /usr/bin/php /path/to/your/laravel/project/artisan storage:link
- 保存退出后,在控制器中改用系统命令调用即可:
// 控制器代码 exec('sudo /usr/bin/php /path/to/your/laravel/project/artisan storage:link');
该方案会给Web用户开放sudo执行特定命令的权限,配置错误可能存在安全隐患,优先选择方案1。
内容的提问来源于stack exchange,提问作者Fredericka Hartman
相关产品推荐
相关产品推荐

