写入共享卷码头

我有个装有 PHP 应用程序的码头

例如,我有一个股票交易量

/home/me/dev/site <=> /var/www/site

我可以在主机中编写一些东西,它将与容器同步

如果我发射的话

sudo docker exec test touch /var/www/site/test.txt

有用

但是如果我的服务器试图创建一个文件作为 www-data,这是不工作的,因为权利。

有没有办法让 www-data访问我的共享卷?

我正在使用 boot2docker

127955 次浏览

(绑定安装的) Docker 卷将维护设置在 Docker 主机本身。您可以使用它来设置这些 文件和目录,然后才在容器中使用它们。

一些背景

Linux 中的权限基于用户和组 身份证('uid'/'gid') 尽管您 是一个用户,而且 姓名作为所有者组,但这些名称实际上并不是 在 Linux 中非常重要,它们的存在只是为了让您更容易查看文件的所有者(它们是从 /etc/passwd文件中查找的)。

可以对文件设置 任何 uid/gid; 用户在设置这些权限时不必设置 存在

touch foobar && sudo chown 1234:5678 foobar && ls -la foobar


# UID and GID are set to 1234 / 5678, even though there's no such user
-rw-rw-r-- 1 1234 5678 0 Mar 25 19:14 foobar

检查权限(容器内外)

如上所述,Docker 在使用 此示例显示卷中的权限和所有权是 相同的 在外面在里面容器;

# (First create a dummy site)


mkdir -p volume-example/site && cd volume-example
echo "<html><body>hello world</body></html>" > site/index.html


# Permissions on the Docker host;


ls -n site


# total 4
# -rw-rw-r-- 1 1002 1002 38 Mar 25 19:15 index.html


# And, permissions inside a nginx container, using it as volume;


sudo docker run --rm -v $(pwd)/site:/var/www nginx ls -n /var/www


# total 4
# -rw-rw-r-- 1 1002 1002 38 Mar 25 19:15 index.html

设置权限

正如所解释的,用户不必为了使用它们而存在,因此即使 我们在 Docker 主机上没有 www-data用户,我们仍然可以设置正确的 权限,如果我们知道该用户在容器内的“ uid”和“ gid”;

让我们看看 www-data 用户的 uid 和 gid 是什么,容器是 在里面;

sudo docker run --rm nginx id www-data


# uid=33(www-data) gid=33(www-data) groups=33(www-data)

首先检查状态 之前更改权限 作为用户 www-data运行 nginx 容器;

sudo docker run \
--rm \
--volume $(pwd)/site:/var/www \
--user www-data nginx touch /var/www/can-i-write.txt


# touch: cannot touch `/var/www/can-i-write.txt': Permission denied

接下来,设置本地目录的权限,看看我们是否能够写;

sudo chown -R 33:33 site


sudo docker run \
--rm \
--volume $(pwd)/site:/var/www \
--user www-data nginx touch /var/www/can-i-write.txt

成功了!

将以下代码行添加到 dockerfile 并重新生成映像

RUN usermod -u 1000 www-data
RUN usermod -G staff www-data

我们发现一个问题,Windows 上的 php-fpm 无法写入/var/www/html 下的文件,但 Mac 可以。是原作者问题的一种变体。

我在 Mac Mojave 上使用 Docker Desktop 4.4.2(10.14.6)。 我有同事在 Windows10上运行 DockerDesktop。

我们的 Docker 容器使用的是 php: 7.1.33-fpm-alpine 映像。

我们有一个主机文件夹映射到/var/www/html 的 docker 容器。

在/usr/local/etc/php-fpm. d 下的 www.conf 将用户、组、 listen.user 和 listen.group 都设置为 www-data。

在 Mac 上,php-fpm 写入/var/www/html 下的文件没有问题。

在 Windows 上,php-fpm 不能写入/var/www/html 下的文件。

我在 Mac 上发现了一些奇怪的东西。共享卷中文件的所有权似乎随着登录到容器中的用户而变化。

如果我使用 docker exec -it ideas-wordpress-1 /bin/sh登录到容器,并使用 ls -l在/var/www/html 中列出文件,那么这些文件都由 root: root 拥有,权限为 rw-r —— r ——。

如果我将 www-data 用户的 shell 从/sbin/nologin 更改为/etc/passwd 中的/bin/sh,并且当我列出/var/www/html 文件夹中的文件时,它们现在属于 www-data: www-data,权限为 rw-r —— r ——。

在 Windows 上,情况有点不同。

如果我使用 docker exec -it ideas-wordpress-1 /bin/sh登录到容器,并使用 ls -l在/var/www/html 中列出文件,那么这些文件都由 root: root 拥有权限-rwxrwxrwx。

如果我将 www-data 用户的 shell 从/sbin/nologin 更改为/etc/passwd 中的/bin/sh,并且当我列出/var/www/html 文件夹中的文件时,它们现在由具有权限-rwxrwxrwx 的 root: root 所拥有。他们没有改变。

我相信这就是为什么 PHP-FPM 可以在 Mac 上而不是在 Windows 上写入挂载卷中的文件。

我想知道我们是否可以让 Docker 维护人员修改 Docker,让 Windows 的操作系统像 Mac 一样。