如何将用户添加到Docker容器?


284

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

我尝试将RUN adduser uwsgi和添加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] 

Answers:


488

诀窍是使用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用户才能执行具有超级用户特权的命令。


141
我建议像在脚本中那样,在Dockerfile中使用全名选项,而不是短名称(在交互式IMO中使用更多选项)。 useradd --create-home --shell /bin/bash对于同事来说更容易理解/理解。
Baptiste Mathus '16

25
为了设置密码,您可以使用chpasswd,例如:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz '16

3
请注意,如果您要创建具有大用户ID的新用户,则docker在尝试创建lastlog(海量稀疏文件)时可能会挂起/崩溃。使用--no-log-init选项可以避免这种情况useradd
davidA

10
很好的提示,@ iuridiniz!别忘了叫它USER newuser。如果还需要用户具有root特权,则还可以包含adduser <username> sudo
Yamaneko '16

6
/bin/sh: useradd: not found高山linux
deathangel908

91

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

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

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

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

RUN adduser -D -g '' newuser

请参阅busybox adduser


3
谢谢!看起来adduser高级解决方案通常比使用像的低级功能更可取useradd
akhmed

adduser: unrecognized option: gecos这似乎不适用于Alpine。
weberc2

--disabled-password的作用是什么?如何在Dockerfile中同时为用户设置密码?
侯赛因

71

的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新帐户的登录外壳。
  • -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


2
用户为什么会在根组中?这不是要出于安全目的而拥有非root用户
吗?

5
@Novaterata取决于用途。root“组”并不表示他们具有root用户访问权限,而只是表示他们具有对某些文件(例如日志)的更多读访问权限,这很有用,但这取决于项目。
kenorb

我看到这可行,我自动以用户身份登录,但是我仍在生成root拥有的文件。我什至只使用了“ USER用户”,因为我在本地用户和组上的用户名是“用户”。仍会生成根拥有的文件。还有什么我应该做的吗?我基本上是在制作一个可以编译我们的代码库的docker容器。因此,它从svn中检出代码,并使用bash源设置变量。即使从未询问过root密码,bash命令也可以root身份运行吗?
JoeManiaci

14

从安全角度来看,在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项目文件,创建用户组和用户,为用户分配项目文件夹权限,切换到新创建的用户并在该用户下运行应用程序的完整示例。


1
addgroup对我来说失败,步骤11/15:RUN addgroup -S用户名--->在db9fd22d469d中运行Option s模棱两可(shell,系统)adduser [--home DIR] [--shell SHELL] [--no-create -home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] [--encrypt-home] USER添加普通用户
播音

9

您可以模仿开源Dockerfile,例如:

节点: node12-github

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

超集: superset-github

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

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


3

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

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回答


1

或者,您可以这样做。

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

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

标志代表:

-G Group
-D Don't assign password
-H Don't create home directory

0

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

RUN useradd -ms /bin/bash yourNewUserName
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.