Laravel 5.6在Ubuntu 16.04上logs/laravel.log权限拒绝问题求助
我明白你现在的头疼——为了让Laravel正常运行不得不给目录开777,但生产环境这么做实在太危险了。结合你用的AWS Ubuntu 16.04 + Apache环境,我给你一套安全且有效的解决方案,顺便解释清楚你之前踩的坑。
核心问题分析
从你贴的ps aux结果来看,Apache确实是以www-data用户运行的。Laravel需要web服务器进程能写入storage(日志、缓存文件)和bootstrap/cache(配置、路由缓存)这两个目录,之前改权限没用,大概率是因为没递归设置组权限,或者忽略了新版Laravel的目录结构变化。
步骤1:安全设置目录权限
1.1 先把项目目录的组统一设为www-data
Apache进程属于www-data组,所以我们要让项目的目录组归给它,同时开放组的读写执行权限:
# 递归修改项目根目录的组为www-data(替换成你的Laravel项目路径) sudo chgrp -R www-data /var/www/your-laravel-project # 递归给组开放读写执行权限(目录需要执行权限才能进入) sudo chmod -R g+rwx storage bootstrap/cache
1.2 细化文件与目录权限(可选但更安全)
如果想进一步收紧权限,确保文件是664(用户/组读写,其他只读),目录是775(用户/组读写执行,其他读执行):
# 设置storage和bootstrap/cache下的文件权限为664 sudo find /var/www/your-laravel-project/storage -type f -exec chmod 664 {} \; sudo find /var/www/your-laravel-project/bootstrap/cache -type f -exec chmod 664 {} \; # 设置目录权限为775 sudo find /var/www/your-laravel-project/storage -type d -exec chmod 775 {} \; sudo find /var/www/your-laravel-project/bootstrap/cache -type d -exec chmod 775 {} \;
步骤2:解决生产环境Blade显示原始文本的问题
这个问题是因为Laravel无法生成模板缓存文件(大概率是bootstrap/cache权限不足)。执行以下命令强制清除旧缓存并重新生成:
# 清除所有缓存 php artisan cache:clear php artisan config:clear php artisan view:clear # 生产环境优化缓存(必须执行,否则模板不会被编译) php artisan config:cache php artisan route:cache php artisan view:cache
执行完后再检查bootstrap/cache目录的权限,确保www-data组有写入权限,模板就能正常编译显示了。
为什么你之前改ubuntu:www-data没用?
你之前把用户设为ubuntu、组设为www-data,但问题在于:Apache的进程是以www-data用户身份运行的,它需要的是组权限(也就是www-data组能读写目录),而不是让ubuntu用户拥有权限。另外,你可能没递归修改权限,导致子目录和文件的权限没同步更新,所以没效果。
关于新版Laravel的bootstrap/cache位置
你观察得很准!从Laravel 5.x开始,bootstrap/cache就从storage目录移到了项目根目录的bootstrap文件夹下,很多旧教程没更新这个点,这也是很多人踩坑的原因——设置权限时漏掉了这个目录,导致缓存写入失败。
额外的安全优化建议
- 绝对不要用
777权限,任何用户都能修改你的文件,生产环境下这是致命的安全漏洞。 - 如果你的服务器支持
setfacl(Ubuntu 16.04默认支持),可以用它来设置默认权限,确保新生成的日志、缓存文件自动拥有正确权限:
sudo setfacl -R -m u:www-data:rwx storage bootstrap/cache sudo setfacl -R -d -m u:www-data:rwx storage bootstrap/cache
第二条命令是设置默认权限,后续生成的新文件都会自动继承www-data的读写权限。
- 用Git的话,记得把
storage/logs/*、bootstrap/cache/*加到.gitignore里,别把敏感的日志和缓存文件提交到仓库。
内容的提问来源于stack exchange,提问作者logikurl

