Docker 如何通过在容器中从头开始设置随机UID来创建非root用户?

Docker 如何通过在容器中从头开始设置随机UID来创建非root用户?,docker,go,dockerfile,Docker,Go,Dockerfile,我正在用Docker设置一个Golang服务器,为了安全起见,我想让一个没有特权的用户在其容器内启动它 下面是我使用的简单Dockerfile。我将二进制文件导入容器并设置一个随机UID FROM scratch WORKDIR /app COPY --chown=1001:1001 my-app-binary my-app-binary USER 1001 CMD ["/app/my-app-binary"] 如果我的服务器侦听端口443,它将无法工作,因为它需要特权。因此,我的应用程序是由

我正在用Docker设置一个Golang服务器,为了安全起见,我想让一个没有特权的用户在其容器内启动它

下面是我使用的简单Dockerfile。我将二进制文件导入容器并设置一个随机UID

FROM scratch
WORKDIR /app
COPY --chown=1001:1001 my-app-binary my-app-binary
USER 1001
CMD ["/app/my-app-binary"]
如果我的服务器侦听端口443,它将无法工作,因为它需要特权。因此,我的应用程序是由一个非特权用户按预期运行的

然而,用户1001没有正确创建。我看到的教程告诉我在一个中间的“builder”容器(例如alpine)中创建用户并从中导入/etc/passwd。我没有发现任何例子做我所做的。(我遵循了一个教程)


有人能给我解释一下为什么我的解决方案有效或者我不明白什么吗?

披露:在我的回答中,我引用了。我既不是这篇文章的作者,也与作者没有任何关系。

这是预期的-容器可以在容器未知的用户下运行。引述:

root
(id=0)是容器中的默认用户。图像开发人员可以创建其他用户。这些用户可以通过名称访问传递数字ID时,用户不必存在于容器中。

--

它可以帮助您解决以下问题:

有时,当我们在Docker容器中运行构建时,构建会在从主机装入容器的文件夹(例如,源代码目录)中创建文件。这会给我们带来痛苦,因为这些文件将由
root
用户拥有。当普通用户在准备下一次构建时尝试清理这些文件时(例如,使用
git clean
),他们会收到一个错误,我们的构建失败

--

这是可能的,因为:

幸运的是,
docker run
为我们提供了一种方法:。我们将使用它来指定Docker应该使用的用户ID(UID)和组ID(GID)。这是因为Docker容器都共享相同的内核,因此UID和GID的列表也是相同的,即使容器不知道相关的用户名(稍后将详细介绍)

--

上述情况也适用于

使用容器不知道的UID有一些问题:

您的用户将减少$HOME 我们在这里实际做的是让Docker容器使用它不知道的用户ID来做一些事情,这会造成一些麻烦。也就是说,这意味着用户缺少了我们所学到的一些东西,而这些东西只是希望用户拥有 — 像主目录之类的东西。这可能会很麻烦,因为这意味着生活在$HOME中的所有东西 — 临时文件、应用程序设置、包缓存 — 现在没有地方住了。集装箱化过程根本不知道把它们放在哪里

当我们尝试做用户特定的事情时,这会影响我们。我们发现,使用
gem安装
(尽管使用Bundler是可以的),或者运行依赖于
ENV['HOME']
的代码会导致问题。因此,这可能意味着,如果你做这两件事中的任何一件,你都需要做一些调整

您的用户也将是匿名的 结果还表明,我们无法在Docker主机及其容器之间轻松共享用户名。这就是为什么我们不能只使用
dockerrun--user=$(whoami)
 — 容器不知道您的用户名。它只能通过其UID来了解您的用户

这意味着当您在容器中运行
whoami
时,您将得到类似
我没有名字这样的结果。这很有趣,但是如果你的代码依赖于知道你的用户名,你可能会得到一些令人困惑的结果

--


披露:在我的回答中,我引用了。我既不是这篇文章的作者,也与作者没有任何关系。

这是预期的-容器可以在容器未知的用户下运行。引述:

root
(id=0)是容器中的默认用户。图像开发人员可以创建其他用户。这些用户可以通过名称访问传递数字ID时,用户不必存在于容器中。

--

它可以帮助您解决以下问题:

有时,当我们在Docker容器中运行构建时,构建会在从主机装入容器的文件夹(例如,源代码目录)中创建文件。这会给我们带来痛苦,因为这些文件将由
root
用户拥有。当普通用户在准备下一次构建时尝试清理这些文件时(例如,使用
git clean
),他们会收到一个错误,我们的构建失败

--

这是可能的,因为:

幸运的是,
docker run
为我们提供了一种方法:。我们将使用它来指定Docker应该使用的用户ID(UID)和组ID(GID)。这是因为Docker容器都共享相同的内核,因此UID和GID的列表也是相同的,即使容器不知道相关的用户名(稍后将详细介绍)

--

上述情况也适用于

使用容器不知道的UID有一些问题:

您的用户将减少$HOME 我们在这里实际做的是让Docker容器使用它不知道的用户ID来做一些事情,这会造成一些麻烦。也就是说,这意味着用户缺少了我们所学到的一些东西,而这些东西只是希望用户拥有 — 像主目录之类的东西。这可能会很麻烦,因为这意味着生活在$HOME中的所有东西 — 临时文件、应用程序设置、包缓存 — 现在没有地方住了。集装箱化的过程根本不知道去哪里