Compose: 支持“docker-compose up”中的--user选项

创建于 2015-06-09  ·  53评论  ·  资料来源: docker/compose

我需要传递--user选项以在我自己的 UID 下运行编排的容器。 这主要是因为挂载的主机卷,我希望 dockerized 应用程序生成我拥有的文件,而不是根目录。

使用docker-compose up ,这是不可能的,至少不是直接的。 现在我正在使用一个疯狂的解决方法:

NAME=`compose run -d --user="$UID" someservicename`
docker rename $NAME ${NAME/_run/}

这是次优的,要温柔。

areconfig

最有用的评论

大约一年前,当我试图解决这个问题时,我发现了这个话题。 由于当时没有提供任何解决方案,我创建了一堆包装 bash 脚本来运行您的 docker-compose。

现在一年后一切都一样了。 我想知道像 docker-compose 这样的软件需要多少时间才能解决这样一个简单的问题,它甚至不是一个真正的提供者,而是一个包装器。

$UID 默认不会在 Linux 上导出,好吗? 这阻止了我们创建一个通用的 docker-compose - 这本身就是一件奇怪的事情,因为这个软件被认为是一个前端解决方案,对吧?

如果你们不喜欢在琐事上浪费时间——我理解——那么为什么不让我们在运行服务之前执行随机主机命令,嗯? 我们可以这样做:

services:
  web:
     ...
     host_command: export UID

这不是很明显吗?

所有53条评论

我不确定我是否理解, docker-compose run --user是一个选项,并且docker-compose.yml支持user键(http://docs.docker.com/compose/yml/ #working95dir-entrypoint-user-hostname-domainname-mem95limit-privileged-restart-stdin95open-tty-cpu95shares)。

我想我们需要在user字段中支持环境变量解析,以便您可以将其设置为$UID对吗? #1377

你好。 是的,在这种情况下, $UID扩展可以解决问题。 尽管如此, $# docker-compose up命令的--user选项(不仅适用于docker-compose run )对于以特定用户身份启动整个项目很有用。

关键是允许在不触及 yml 的情况下指定用户。

以特定用户身份启动整个项目

我从来没有想过人们可能想要这样做。 你能详细说明一下用例吗?

没关系,我向上滚动。 我认为你在 Linux 上是对的吗? 使用 boot2docker 时,它会创建具有合理权限的文件。

我想知道是否有一种方法可以配置 Docker 守护程序来为它安装的每个卷执行此操作。

是的,在 Linux 上。

我正在使用 compose 通过挂载主机卷在 CI 上运行测试(是的,我知道)。 如果没有此选项,某些文件会以“错误”的所有权创建,即root:root

我知道我可以使用仅数据容器并从中检查/复制文件,但是主机卷更方便并且需要更少的脚本。

如果某些容器/服务已经指定了用户, up --user可能会很危险。

@mrzechonek我不认为因为环境而修改容器是一个好习惯。

@josphpage是的,它可能是。 $UID 扩展虽然可以解决问题。

几乎我唯一需要的是对主机卷的适当权限。 除了将容器进程作为 $UID 运行之外,我不知道有任何其他方法可以实现这一点......

我实际上更希望这个功能出现在 Damon 本身中,就像@aanand说的那样。 或者也许可以选择以这种模式安装卷(可能是存储驱动程序?)。

@mrzechonek ,您找到解决方法了吗?

不是真的,不。 现在我们正在做docker-compose run --user然后重命名/重新标记容器以使compose认为它是由up命令启动的,因此stopps会起作用。

1377 在 master 中,将在 1.5.0 版本中,因此您可以在docker-compose.yml中执行user: $UID #$ 。 如果您对使用 master 感到满意,您现在可以尝试一下,否则 RC 版本应该会在接下来的几周内发布。

我将关闭此问题,因为该功能本身是作为 #1377 的一部分实现的

然后重命名/重新标记容器以使 compose 认为它是由 up 命令启动的

这实际上不是我第一次听说需要这个(尽管在这种情况下我猜这只是暂时的)。 我在 #2042 中提出了修复建议

谢谢,#1377 很好地解决了这个问题。

@mrzechonek你能澄清一下这是如何解决你的问题的吗? 我有完全相同的用例:“我希望 dockerized 应用程序生成我拥有的文件,而不是根”

我尝试将user: $UID添加到web容器中,当我使用docker-compose run web touch foo时,我得到以下信息:

WARNING: The UID variable is not set. Defaulting to a blank string.

文件foo已创建,但仍归root拥有。

我用过user: $USER ,但$UID也可以。 我不知道为什么您的设置抱怨缺少变量:(

与@michaelmior 有完全相同的问题。

当使用 $USER 时,我得到System error: Unable to find user Max 。 这是有道理的,因为它是主机用户。

什么可能导致 $UID 在 docker-compose 执行期间不可用?

你好,这里有同样的问题。
我在 Fedora 23 上,当我在主机上调用env命令时,不会传播 UID 变量。

解决方法:
首先在主机上执行export UID ,然后调用您的docker-compose

如果 docker-compose 只是让$UID可用而不必导出它会很好。 最终成为样板。

如果UID未导出,则 compose 无法获取它,所以我认为您的要求是不可能的。

那么,作为一个正在运行的应用程序简单地编写它无法推断它正在运行的用户吗?

当然,它可以读取$USER环境变量,但您也可以从 Compose 文件中读取! 如果未导出变量,则子进程将无法使用它。 真正简单的解决方案似乎只是导出它。

我更多地认为,如果没有声明 UID,那么可执行文件可以查看运行它的 uid 并使其可用。

再次,考虑样板和容易忽略的步骤。 大多数人想要一个设置,其中唯一的步骤是docker-compose up 。 为什么要添加一个微小的变量要求,即 99% 的人都将以完全相同的方式设置。

是否有一个很好的资源可以说明 Mac 和 Linux 主机之间的任何其他类似问题?

此外,在 Linux 上强制用户并不是我们真正想要的,我们想要 Mac 的行为,即使您在容器中以 root 身份运行,主机卷上的新文件也具有有用的权限:(

实际上,我只是对为什么我的 Mac 行为比我的 Linux 行为更好感到困惑,而且这与这个问题没有任何关系。 我在 Dinghy 上开始了一个问题,以寻找在 Linux 上获得良好体验的解决方案。

@mrzechonek你能分享你如何使用user:指令来确保主机和容器上的文件权限正确吗?

我只是将user: $UID添加到.yml文件中。 那是在 Linux、Gentoo 和 Ubuntu 12.04 上。

@mrzechonek谢谢。 然后你的容器会做一些运行时魔法吗? 据我了解, user:反映了 Dockerfile 指令。 但这仅仅意味着容器内的命令作为user: $UID运行。 我无法理解这对卷权限有什么帮助=/。

@mrzechonek :这是不同的。 我们想要一个功能来控制容器在主机系统外部充当的用户,而不管它在容器本身内部被设置为谁。

想一想:_" root在容器中写为myuser用户在主机上"_.

在我们的用例中,几乎总是同一个用户构建容器并运行它,所以没有问题。

但是,如果您想“动态地”将容器用户映射到主机用户,我认为唯一的方法是在 docker daemon 本身中支持 LXC 用户命名空间,该功能尚未实现(还没有?就我而言)知道?)。

我不认为这是docker-compose可以做的事情。

好像我错过了几个版本: https ://integratedcode.us/2015/10/13/user-namespaces-have-arrived-in-docker/

抱歉,我不再使用 Docker,至少在当前项目中没有积极使用。

谢谢@mrzechonek。 最终,我正在尝试做@gkop正在尝试做的事情——将容器生成的文件放在容器启动器拥有的主机安装卷上。 这就是它在带有最新 Docker 1.12 beta 的 OS X 上的工作方式(如何?),这也是我希望在 linux 上看到它的方式。

@mrzechonek - 一些应用程序要求它们作为特定用户运行,或者要求它们运行的​​用户映射到系统中的真实用户。 在这些情况下,将其保留为 root 并在容器的头部进行映射会更容易。

(这代替了许多丑陋的黑客将当前正在运行的系统的用户方案映射到容器上,只是为了让所有东西都排好)

@dmitrym0我认为在 OSX 下,您在本机 OSX 虚拟化(https://github.com/mist64/xhyve/)中运行boot2docker ,然后在该 VM 中创建容器。 这意味着它实际上是 VM 执行所有用户映射,而不是 docker 守护进程。 容器的root仍然是主机的root

Ubuntu 16.04 主机上默认未设置 $UID。 docker-compose 获取运行它的用户 ID 并注入它是微不足道的。 为 app dev compose 用户设置的样板代码和环境要少得多,这是有道理的,因为 compose 完全是关于 docker UX。

+1 用于 docker-compose up --user 或执行用户 ....

有没有关于这个问题的解决方案或消息?

不,我不久前针对 docker 引擎打开了此功能: https ://github.com/docker/docker/issues/22415

我认为这是一个比目前公认的影响更大的问题。 能够改变容器接触文件系统的用户,而不必让容器本身知道权限系统会打开很多门。

如果您对此感兴趣,我建议您分享和支持我链接的票。

这对我有用: user: "1000:1000"

@jovanialferez仅供参考,如果您像这样对其进行硬编码,如果其他人参与了未将其 UID 和 GID 设置为 1000 的项目,您将遇到麻烦。我认为 OSX 开始将普通用户编号为 500,任何 Linux与多个用户一起安装最终会得到大于 1000 的 UID。

@jovanialferez只能在 Linux 上运行。

著名的。 谢谢@nfm @luispabon

我最近从 Mac 迁移到 Linux,只是受到了打击,不太明白这个问题是怎么解决的

再次提这个问题让新人看到: https ://github.com/moby/moby/issues/22415

我们确实需要能够从外部将 docker 进程映射到特定用户。 重视外在。 不选择容器中进程的UID/GID。 但是将容器进程从外部映射到本地 UID/GID。

确实是的。 将当前用户的 uid/gid 分配到容器中仅适用于 Linux。 不过,这似乎是一个码头问题。

我们在 Windows 上遇到了一个更深奥的问题。 我们使用 OrientDB 本地实例,它将文件写入主机的文件系统,而在 Windows 上似乎没有这样做。 哦...可能是因为主机卷不是块卷?

大约一年前,当我试图解决这个问题时,我发现了这个话题。 由于当时没有提供任何解决方案,我创建了一堆包装 bash 脚本来运行您的 docker-compose。

现在一年后一切都一样了。 我想知道像 docker-compose 这样的软件需要多少时间才能解决这样一个简单的问题,它甚至不是一个真正的提供者,而是一个包装器。

$UID 默认不会在 Linux 上导出,好吗? 这阻止了我们创建一个通用的 docker-compose - 这本身就是一件奇怪的事情,因为这个软件被认为是一个前端解决方案,对吧?

如果你们不喜欢在琐事上浪费时间——我理解——那么为什么不让我们在运行服务之前执行随机主机命令,嗯? 我们可以这样做:

services:
  web:
     ...
     host_command: export UID

这不是很明显吗?

+1

这个问题没有足够的赞和+1,对我来说,这是一个被包括我自己在内的许多用户忽视但需要和要求的问题。

我也在这里给我+1,因为我被这个击中了。 我目前不希望我的容器以 root 身份运行 - 但我希望它们在主机中共享一个可由我的用户写入的卷。 如果我不设置用户,则无法做到这一点,而扩展将是最自然的方法,而不是user: 1000:1000 ,因为如前所述,它会导致与其他环境的用户发生冲突。 $UID,即使它没有被导出,也被证明是一个更好的解决方案,因为它基于环境而不是基于 docker-expose。

只是我的2美分。 那么,无论如何,有人找到了一种方法吗?

@darkguy2008 - 一定要大肆宣传这个: https ://github.com/moby/moby/issues/22415

我怀疑在 compose 可以在其之上构建之前,docker 本身需要一个功能。

我不确定我是否理解, docker-compose run --user是一个选项,并且docker-compose.yml支持user键(http://docs.docker.com/compose/yml/ #working95dir-entrypoint-user-hostname-domainname-mem95limit-privileged-restart-stdin95open-tty-cpu95shares)。

我想我们需要在user字段中支持环境变量解析,以便您可以将其设置为$UID对吗? #1377

链接已损坏。

发现添加强制变量有助于解决问题:

version: "3"
services:
  testapp:
    image: ubuntu:20.04
    entrypoint: /bin/bash -c "cd $PWD && touch tmp"
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}
    volumes:
      - $PWD:$PWD

会显示:

ERROR: Missing mandatory value for "user" option in service "testapp": "Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"

指定文件必须像这样执行:

CURRENT_UID=$(id -u):$(id -g) docker-compose up

发现添加强制变量有助于解决问题:

version: "3"
services:
  testapp:
    image: ubuntu:20.04
    entrypoint: /bin/bash -c "cd $PWD && touch tmp"
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}
    volumes:
      - $PWD:$PWD

会显示:

ERROR: Missing mandatory value for "user" option in service "testapp": "Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"

指定文件必须像这样执行:

CURRENT_UID=$(id -u):$(id -g) docker-compose up

问题是我的服务需要root访问权限才能启动。 例如:

app-php-fpm  | [14-Jun-2020 00:15:12] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
app-php-fpm  | [14-Jun-2020 00:15:12] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
app-redis    | 1:M 14 Jun 2020 00:15:12.710 * Ready to accept connections
app-php-fpm  | [14-Jun-2020 00:15:12] ERROR: Unable to create the PID file (/run/php-fpm.pid).: Permission denied (13)
app-php-fpm  | [14-Jun-2020 00:15:12] ERROR: FPM initialization failed
app-webserver exited with code 1
app-mysql exited with code 1
app-php-fpm exited with code 78
此页面是否有帮助?
0 / 5 - 0 等级