如何防止Laravel项目存储目录所有者变更及配置生产报错通知
A 避免目录所有者变更导致运行异常的方案
- 先明确权限突变的核心原因:大多是不同用户对storage目录执行了写入操作,比如用ec2-user手动执行artisan命令、composer安装扩展,部署脚本配置了错误的执行用户,或者定时任务、队列服务用非apache用户启动,都会导致新生成的文件/目录所有者异常。
- 第一步:给storage和bootstrap/cache目录设置SGID权限,保证目录下所有新生成的文件自动继承父目录的用户组,不会因为创建用户不同出现组权限不匹配:
# 递归设置所属用户组 sudo chown -R ec2-user:apache /var/www/html/storage /var/www/html/bootstrap/cache # 递归设置SGID位+读写执行权限,2对应SGID位 sudo chmod -R 2775 /var/www/html/storage /var/www/html/bootstrap/cache
- 第二步:统一所有操作的执行权限
- 把日常操作用户ec2-user加入apache组,避免组权限不足:
sudo usermod -aG apache ec2-user - 调整系统默认umask为002,保证所有用户新建的文件/目录权限为775/664,组成员有可写权限
- 所有手动执行的artisan、composer操作,还有部署脚本、定时任务、队列worker服务,都统一用apache用户执行,或者确认执行用户在apache用户组内
- 把日常操作用户ec2-user加入apache组,避免组权限不足:
- 兜底方案:写个轻量定时脚本,每分钟校验一次storage目录的权限和所有者,不符合规则就自动修正,脚本参考:
#!/bin/bash TARGET_PATH="/var/www/html/storage" EXPECT_OWNER="ec2-user:apache" EXPECT_PERM="2775" CURRENT_OWNER=$(stat -c "%U:%G" $TARGET_PATH) CURRENT_PERM=$(stat -c "%a" $TARGET_PATH) if [ "$CURRENT_OWNER" != "$EXPECT_OWNER" ] || [ "$CURRENT_PERM" != "$EXPECT_PERM" ]; then chown -R $EXPECT_OWNER $TARGET_PATH chmod -R $EXPECT_PERM $TARGET_PATH fi
将脚本加入root用户的crontab,设置每分钟执行一次即可。
B Laravel生产环境权限异常通知配置
- 方案1:通过Laravel自带的异常处理器自定义告警
先在.env文件配置好可用的邮件发送参数,再修改app/Exceptions/Handler.php的register方法,新增异常上报逻辑:
public function register() { $this->reportable(function (Throwable $e) { // 仅生产环境触发告警 if (!app()->environment('production')) { return; } // 匹配权限相关的异常关键词,可根据实际场景补充 $errorKeywords = [ 'Unable to create lockable file', 'permission denied', 'Permission denied', 'ensure you have permission to create files' ]; foreach ($errorKeywords as $keyword) { if (str_contains($e->getMessage(), $keyword)) { // 发送邮件告警,也可自行对接钉钉、企业微信webhook发送更即时的通知 \Mail::raw('生产环境权限异常:' . $e->getMessage() . PHP_EOL . '异常堆栈:' . $e->getTraceAsString(), function ($message) { $message->to('运维/开发人员邮箱地址') ->subject('生产环境Laravel权限异常告警'); }); break; } } }); }
- 方案2:配合日志监控工具告警
把Laravel生产环境的日志级别调整为error,用服务器日志采集工具(比如rsyslog、自建ELK栈)配置关键词告警规则,只要日志中出现权限相关的错误关键词就触发通知,覆盖所有未被异常处理器捕获的场景。
内容的提问来源于stack exchange,提问作者Adriaan De Bolle
相关产品推荐
相关产品推荐

