417

我有一个 docker 容器,里面运行着一些进程(uwsgi 和 celery)。我想为这些进程创建一个 celery 用户和一个 uwsgi 用户,以及它们都属于的工作组,以便分配权限。

我尝试将RUN adduser uwsgiand添加RUN adduser celery到我的 Dockerfile 中,但这会导致问题,因为这些命令会提示输入(我已经发布了来自下面构建的响应)。

将用户添加到 Docker 容器以便为在容器中运行的工作人员设置权限的最佳方法是什么?

我的 Docker 镜像是从官方的 Ubuntu14.04 基础构建的。

以下是运行 adduser 命令时 Dockerfile 的输出:

Adding user `uwsgi' ...
Adding new group `uwsgi' (1000) ... 
Adding new user `uwsgi' (1000) with group `uwsgi' ... 
Creating home directory `/home/uwsgi' ...
Copying files from `/etc/skel' ... 
[91mEnter new UNIX password: Retype new UNIX password: [0m 
[91mpasswd: Authentication token manipulation error
passwd: password unchanged
[0m 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 563.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 564.
[0m 
Try again? [y/N] 
Changing the user information for uwsgi
Enter the new value, or press ENTER for the default
    Full Name []: 
Room Number []:     Work Phone []:  Home Phone []:  Other []: 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 589.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 590.
[0m 
Is the information correct? [Y/n] 
---> 258f2f2f13df 
Removing intermediate container 59948863162a 
Step 5 : RUN adduser celery 
---> Running in be06f1e20f64 
Adding user `celery' ...
Adding new group `celery' (1001) ... 
Adding new user `celery' (1001) with group `celery' ... 
Creating home directory `/home/celery' ...
Copying files from `/etc/skel' ... 
[91mEnter new UNIX password: Retype new UNIX password: [0m 
[91mpasswd: Authentication token manipulation error
passwd: password unchanged
[0m 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 563.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 564.
[0m 
Try again? [y/N] 
Changing the user information for celery
Enter the new value, or press ENTER for the default
    Full Name []:   Room Number []:     Work Phone []: 
Home Phone []:  Other []: 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 589.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 590.
[0m 
Is the information correct? [Y/n] 
4

8 回答 8

675

诀窍是使用useradd而不是它的交互式包装器adduser。我通常使用以下方式创建用户:

RUN useradd -ms /bin/bash newuser

它为用户创建一个主目录并确保 bash 是默认 shell。

然后您可以添加:

USER newuser
WORKDIR /home/newuser

到你的 dockerfile。之后的每个命令以及交互式会话都将以用户身份执行newuser

docker run -t -i image
newuser@131b7ad86360:~$

在调用用户命令之前,您可能必须newuser授予执行您打算运行的程序的权限。

出于安全原因,在容器内使用非特权用户是一个好主意。它也有一些缺点。最重要的是,从您的图像派生图像的人必须切换回 root 才能以超级用户权限执行命令。

于 2014-12-30T10:05:10.143 回答
155

Ubuntu

尝试以下行Dockerfile

RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1001 ubuntu
USER ubuntu
WORKDIR /home/ubuntu

useradd选项(见:)man useradd

  • -r,--system创建系统帐号。请参阅:创建系统帐户的含义
  • -m,--create-home创建用户的主目录。
  • -d,--home-dir HOME_DIR新帐户的主目录。
  • -s,--shell SHELL新帐号的登录shell。
  • -g,--gid GROUP主要组的名称或 ID。
  • -G,--groups GROUPS补充组列表。
  • -u,--uid UID指定用户 ID。请参阅:了解 uid 和 gid 如何在 Docker 容器中工作
  • -p,--password PASSWORD新帐户的加密密码(例如ubuntu)。

设置默认用户密码

要设置用户密码,请添加-p "$(openssl passwd -1 ubuntu)"useradd命令。

或者将以下行添加到您的Dockerfile:

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN echo 'ubuntu:ubuntu' | chpasswd

第一个shell 指令是确保该选项在使用管道-o pipefail之前已启用。RUN阅读更多:Hadolint:整理你的 Dockerfile

于 2018-04-16T01:31:12.843 回答
111

为了避免 adduser 的交互式问题,您可以使用以下参数调用它:

RUN adduser --disabled-password --gecos '' newuser

--gecos参数用于设置附加信息。在这种情况下,它只是空的。

在带有busybox的系统(如Alpine)上,使用

RUN adduser -D -g '' newuser

busybox adduser

于 2015-04-22T12:15:24.470 回答
33

从安全角度来看,在 docker 中添加用户并在该用户下运行您的应用程序是非常好的做法。为此,我建议执行以下步骤:

FROM node:10-alpine

# Copy source to container
RUN mkdir -p /usr/app/src

# Copy source code
COPY src /usr/app/src
COPY package.json /usr/app
COPY package-lock.json /usr/app

WORKDIR /usr/app

# Running npm install for production purpose will not run dev dependencies.
RUN npm install -only=production    

# Create a user group 'xyzgroup'
RUN addgroup -S xyzgroup

# Create a user 'appuser' under 'xyzgroup'
RUN adduser -S -D -h /usr/app/src appuser xyzgroup

# Chown all the files to the app user.
RUN chown -R appuser:xyzgroup /usr/app

# Switch to 'appuser'
USER appuser

# Open the mapped port
EXPOSE 3000

# Start the process
CMD ["npm", "start"]

以上步骤是复制 NodeJS 项目文件、创建用户组和用户、为用户分配项目文件夹的权限、切换到新创建的用户并在该用户下运行应用程序的完整示例。

于 2019-01-30T17:18:20.373 回答
20

你可以模仿开源的Dockerfile,例如:

节点: node12-github

RUN groupadd --gid 1000 node \
    && useradd --uid 1000 --gid node --shell /bin/bash --create-home node

超集: 超集-github

RUN useradd --user-group --create-home --no-log-init --shell /bin/bash 
    superset

我认为这是遵循开源的好方法。

于 2019-08-02T06:43:51.440 回答
8

每个人都有自己的最爱,这是我的:

RUN useradd --user-group --system --create-home --no-log-init app
USER app

参考:man useradd

RUN行将添加用户和组app

root@ef3e54b60048:/# id app
uid=999(app) gid=999(app) groups=999(app)

使用比app图像要作为基础图像重用的更具体的名称。顺便说一句,--shell /bin/bash如果您确实需要,请包括在内。


部分学分:Ryan M 的回答

于 2019-08-19T21:18:47.593 回答
4

或者,您可以这样做。

RUN addgroup demo && adduser -DH -G demo demo

第一个命令创建名为demo的组。第二个命令创建演示用户并将他添加到先前创建的演示组。

标志代表:

-G Group
-D Don't assign password
-H Don't create home directory
于 2020-02-06T19:25:27.380 回答
0

将此行添加到您的 Dockerfile(您可以通过这种方式运行任何 linux 命令)

RUN useradd -ms /bin/bash yourNewUserName
于 2015-11-23T15:42:41.910 回答