解决 Docker PHP “Failed opening required ‘xxx.php'” 的问题

这个问题是我最近迁移本网站时遇到的。

本网站是 Docker + PHP-FPM + nginx,迁移后,Wordpress 的 .php 访问报错:Failed opening required /xxx/wp-config.php

很明显就是容器里没有权限。那么为什么会没权限呢?

很久没搞这个的部署,忘得差不多了。经过重温与找资料,大概是这样解决的,不一定是完美的方案:

原因:

  • Docker 的 PHP 运行的时候,默认是用www-data用户(并且uid=33),属于www-data用户组(且gid=33)
  • 某些系统自带了该用户与用户组(例如我网站迁移前所在的机器),某些没有自带(例如现机器)

解决:

  1. 检查宿主机的用户、用户组是否有www-data,且 33 号的 uid/gid 是否被占用:
    # cat /etc/group
    # cat /etc/passwd
  2. 发现用户组 gid=33 被名为“tape”的用户组占用了(我的机器如此),似乎没有什么机会用到这个用户组,所以我把它的 id 改成 34:
    # groupmod -g 34 tape
  3. 创建 gid=33 的www-data用户组:
    # groupadd -g 33 www-data
  4. 创建 uid=33 的www-data用户,不创建home目录(-M),设置默认shell(-s)为nologin:
    # useradd -M -u 33 -g www-data -s /usr/sbin/nologin www-data

    至于为什么要这样创建,是为了尽可能模拟自带的www-data用户,在自带的机器上,passwd文件是这样的:
    # cat /etc/passwd | grep www-data
    www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

    而执行上述 useradd 后,passwd 是这样的,已经很像了:
    www-data:x:33:33::/home/www-data:/usr/sbin/nologin
  5. 最后,在宿主机,把缺少权限的整个目录所有权,赋予给www-data
    # chown -R www-data:www-data some_directory

发表评论