linux目录权限问题排查

PHP的master进程用户和worker进程用户

Posted by 张晨 on June 16, 2021

问题描述

哦豁。线上报错了。报错如下。

今天这篇文章就是讲解我们如何解决如下这个报错。有哪一些注意事项。解决思路是什么?

问题原因

先说说这个报错的原因是什么。按照报错的提示,我们可以看出。我们PHP调用了mkdir,想创建一个文件夹。但是无奈,我们却没有权限创建这个文件夹。

所以,这是什么原因啦?我们为什么没有权限创建这个文件夹啦?我要怎么样才可以创建啦?

排查步骤

说一个前提啊。出现上面这个错误是在阿里云函数计算的环境。我们打包了一个docker的基础镜像,就只有PHP和nginx配合的运行环境。

以下过程都是我模拟出来的哈。

写在前面。你必须懂Linux的目录权限,才可以看懂下面的内容。不然的话你可能会一脸懵逼。Linux目录权限

查看我们要创建目录的权限

我们看到。当前目录是www用户的权限。我们先进入容器看一下。我们能不能在这个目录里面创建文件。

进入容器,新建一个index.html的文件。诶。奇怪了。没有问题啊。我们新增成功了啊。顺利得很啦。访问一下看看。

可以访问。顺利的很。

那是为什么啦?

那我们再试试新建一个PHP的文件。使用PHP代码创建一个文件或者一个目录看看

新建test.php

1
2
3
4
<?php

mkdir('./a/b/c', 0777, true);
echo 'success';

访问。哦豁。报错了。

这是为什么啦?我们刚才在命令行都可以新建文件,并且还可以访问。为什么在PHP里面就不行了啦?

聪明的同学可以先思考几分钟。


可能部分同学已经知道为什么了。

原因就是,其实刚才我们进入容器是root用户。root用户是个无敌的用户,它想干嘛就干嘛。但是PHP在执行的时候,不一定是用root用户的。

那我们PHP到底是什么用户执行的啦?

我们可以执行ps 命令看一下。

得到的结果是。我们的php的master进程是root用户运行的。但是worker进程是www-data用户运行的。

这里稍微提一点题外话啊。master进程负责接收请求,worker进程负责执行代码。

所以,我们刚才PHP执行的创建文件夹的命令,其实是www-data用户在执行。但是当前目录。我们的权限是,其他用户不可以写入数据。所以www-data是不可以在当前目录下面创建文件夹的。


感觉自己已经找到了问题的所在。但是,我们要怎么解决问题啦。怎么解决啦?

又到聪明的你思考问题的时候了。请先自己思考几分钟。

好样的,我们可以把PHPfpm的执行用户给改了。我们也改成www用户不就行了吗?

你简直就是个天才。就是干

1
2
3
4
5
# 添加用户
adduser --disabled-password --no-create-home -s /sbin/nologin  www

# 修改www.conf文件
vi /usr/local/etc/php-fpm.d/www.conf

搞定。重启。看看效果。

赶紧的去执行一下我们的test.php看看效果吧。迫不及待了。

哦豁。还是不能创建。忽悠我啦?老师。

聪明的同学,请你自己思考一会。


其实原因是这样的。我们在宿主机中的www用户的用户id是501(其实我是故意的)。但是在docker容器中,我们的www用户的uid是1000。

在linux系统里面是用uid来标识用户的。并不是用名字来标识的。

我们在容器执行ls -la看一下。就知道了

当前目录的所属用户和所属组都是501。但是PHP的执行用户是1000。所以,你没有权限操作。

现在知道你要干什么吗?

你要在docker里面也创建一个uid为501的用户。并且把它设置为PHP的执行用户。最好是nginx和phpfpm都是用这个用户执行。

参考文档

没有参考文档。全靠头脑发热。