从 docker-compose.yml 中提取了两个容器(删节):
version: '3'
services:
nginx:
image: nginx:alpine
volumes:
- sockets:/srv/unix-sockets
php54-fpm:
image: php:5.4-fpm
volumes:
- sockets:/srv/unix-sockets
volumes:
sockets:
php-fpm创建一个套接字/srv/unix-sockets/php54-fpm.sock,这在nginx.
让我们看看里面的权利php-fpm:
ls -la /srv/unix-sockets/php54-fpm.sock
srw-rw---- 1 root root 0 Dec 18 16:59 /srv/unix-sockets/php54-fpm.sock
套接字是以 root 身份创建的,因为此服务以该用户身份运行。好的,让我们更改所有者:
chown www-data:www-data /srv/unix-sockets/php54-fpm.sock
现在我们进入容器nginx并检查权限:
ls -la /srv/unix-sockets/php54-fpm.sock
srw-rw---- 1 xfs xfs 0 Dec 18 16:59 /srv/unix-sockets/php54-fpm.sock
xfs!!!好的,这是不言自明的:
nginx:
id xfs
uid=33(xfs) gid=33(xfs) groups=33(xfs),33(xfs)
php-fpm:
id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
原来socket的所有者的uid是一样的,在不同的容器中socket属于不同的用户。
但是由于这种行为,工人nginx看不到套接字,error_log这属于:
2019/12/18 16:52:23 [crit] 8#8: *3 connect() to unix:/srv/unix-sockets/php54-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 88.888.88.88, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/srv/unix-sockets/php54-fpm.sock:", host: "77.777.77.77"
有这样的选择:
- 在容器中强制更改/创建具有相同 uid 的 www-data 用户(看起来像拐杖)
- 更改套接字的权限
chmod o+rw(也是马马虎虎) - 其他一些选择
如何正确解决这个问题?
不,这不是拐杖,而是工作的必要条件(许可)。问题是 docker 卷是以 root 身份安装的。唯一的解决方法是编写一个入口点脚本,该脚本将在安装卷后运行,然后启动服务器。
一个不好的问题解决方案,如果有一个入口点,没有它是行不通的。
不要对 *.sock 使用音量。这将是正确的选择。通过 tcp 运行 php-fpm。在 nginx.conf 中,在 docker domain 中写入符号
proxy_pass http://php54-fpm.$COMPOSE_PROJECT_NAME_default:port,其中是php54-fpm服务default的名称,默认创建的网络的名称。作为提示,如果可能的话,不要使用音量,不要使用。