Linux 解决 Laravel 命令行与 Web 进程用户不一致的权限问题

在 Ubuntu 环境中,日常部署代码、执行 Composer 与 Artisan 命令,一般使用 ubuntu 普通用户;
而 Nginx、PHP-FPM 等 Web 服务默认以低权限用户 www-data 运行。

CLI 命令行用户与 Web 运行用户不一致,会直接造成 storagebootstrap/cache 目录读写拒绝、缓存生成失败、日志写入异常等权限问题。

一、统一用户方案

通过让 Web 与命令行共用同一运行用户,从根源规避权限冲突,分为两种实现方式:

1. Web 进程统一使用 ubuntu 用户

修改 PHP-FPM 配置,将进程执行用户改为 ubuntu
操作简单、彻底杜绝权限报错,日常维护最省心。

缺点是会扩大 Web 进程权限范围,存在一定安全隐患。
适合场景:单机单站、个人项目、自用服务、开发/自建生产环境。

2. 命令行统一使用 www-data 用户

保持 PHP-FPM 默认 www-data 隔离权限,执行 Laravel 相关命令时,手动切换为该用户运行。

示例:

1
sudo -u www-data php artisan view:cache

优势是保留系统原生安全隔离,适配企业生产、多站点服务器;
劣势为每次执行 Artisan、Composer 都需要追加用户切换命令,操作繁琐且容易遗漏。

二、附属组 + SGID 标准隔离方案(生产推荐)

该方案是 Laravel 生态公认最佳实践,兼顾安全性与运维便捷性,也是线上生产环境的主流配置。

核心思路: 不改动 Web 服务默认运行用户,通过附属组授权 + SGID 目录继承权限,让两个不同用户互相读写项目临时目录。

  1. ubuntu 追加加入 www-data 附属组,保留原有用户组权限不变;

务必使用 usermod -aG 追加模式,**不可省略 -a**,避免覆盖原有附属组导致权限丢失。

  1. 对读写高频目录绑定归属组,并配置 SGID 权限,使新文件自动继承目录属组,永久解决文件属主错乱问题。

执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 追加用户至 www-data 组
sudo usermod -aG www-data ubuntu

# 关键读写目录统一归属 www-data
sudo chown -R www-data:www-data storage bootstrap/cache

# 给目录 775 权限
sudo chmod -R 775 storage bootstrap/cache

# 给文件 664 权限
sudo chmod -R 664 storage/* bootstrap/cache/*

# 配置 SGID,新建文件/目录自动继承所属组
sudo chmod -R g+s storage bootstrap/cache

# 退出 ubuntu 用户后重新登录,即可生效

这样,名ubuntu用户执行 Artisan 命令时,在 storage 或 bootstrap/cache 目录生成的文件用户为 ubuntu:www-data,php-fpm 生成的文件用户为 www-data:www-data,两者都可以对项目临时目录进行读写操作。

拓展:若业务安全要求极高,可搭配 Ubuntu ACL 精细化授权,进一步收紧权限范围,本文不做展开。