Как добавить пользователей в Docker-контейнер?


286

У меня есть докер-контейнер с некоторыми процессами (uwsgi и сельдерей), работающими внутри. Я хочу создать пользователя celery и пользователя uwsgi для этих процессов, а также рабочую группу, к которой они оба будут принадлежать, для назначения разрешений.

Я попытался добавить RUN adduser uwsgiи RUN adduser celeryв свой Dockerfile, но это вызывает проблемы, так как эти команды запрашивают ввод (я разместил ответы из сборки ниже).

Каков наилучший способ добавления пользователей в контейнер Docker, чтобы установить разрешения для рабочих, работающих в контейнере?

Мой образ Docker собран из официальной базы Ubuntu14.04.

Вот вывод из Dockerfile при запуске команд adduser:

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] 

Ответы:


489

Хитрость заключается в том, чтобы использовать useraddвместо своей интерактивной оболочки adduser. Я обычно создаю пользователей с:

RUN useradd -ms /bin/bash newuser

который создает домашний каталог для пользователя и гарантирует, что bash является оболочкой по умолчанию.

Затем вы можете добавить:

USER newuser
WORKDIR /home/newuser

в ваш докер-файл. Каждая команда впоследствии, а также интерактивные сеансы будут выполняться как пользователь newuser:

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

Возможно, вам придется дать newuserразрешения на запуск программ, которые вы собираетесь запускать, прежде чем вызывать команду пользователя.

Использование непривилегированных пользователей внутри контейнеров является хорошей идеей из соображений безопасности. У этого также есть несколько недостатков. Самое главное, что люди, получающие изображения из вашего изображения, должны будут переключиться обратно в root, прежде чем они смогут выполнять команды с привилегиями суперпользователя.


143
Я бы рекомендовал использовать параметры полного имени в Dockerfile, как в скрипте, вместо коротких (больше для использования в интерактивном режиме IMO). useradd --create-home --shell /bin/bashявляется более понятным / читаемым для коллег.
Батист Матус

25
Чтобы установить пароль, вы можете использовать chpasswd как:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz

3
Обратите внимание, что если вы создаете нового пользователя с большим идентификатором пользователя, докер может зависнуть / зависнуть при попытке создать lastlog - большой разреженный файл. Избегайте этого с --no-log-initвозможностью useradd.
davidA

10
Хороший совет, @iuridiniz! Не забудьте позвонить раньше USER newuser. Если вам также нужно, чтобы у пользователя были права root, вы также можете включить adduser <username> sudo.
Яманеко

6
/bin/sh: useradd: not foundальпийский linux
deathangel908

92

Чтобы избежать интерактивных вопросов от adduser, вы можете вызвать его с помощью следующих параметров:

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

--gecosПараметр используется для установки дополнительной информации. В этом случае он просто пуст.

В системах с busybox (например, Alpine) используйте

RUN adduser -D -g '' newuser

Смотрите Занятый Adduser


3
Спасибо! Похоже, что adduserвысокоуровневое решение обычно предпочитают использовать низкоуровневые функции, такие как useradd.
Ахмед

adduser: unrecognized option: gecosПохоже, это не работает на Alpine.
weberc2

что делает --disabled-пароль и как мы можем одновременно установить пароль для пользователя в Dockerfile?
Хоссейн

72

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Имя или идентификатор первичной группы.
  • -G, --groups GROUPSСписок дополнительных групп.
  • -u, --uid UIDУказать идентификатор пользователя. смотрите: Понимание того, как 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

Первая инструкция оболочки состоит в том, чтобы убедиться, что -o pipefailопция включена перед тем, RUNкак в ней есть канал. Читайте больше: Hadolint: Linting ваш Dockerfile .


2
Почему пользователь будет в корневой группе? Разве не весь смысл в том, чтобы в целях безопасности был пользователь без
полномочий root

5
@Novaterata В зависимости от использования. rootГруппа не указывает, что у них есть root-доступ, просто у них больше прав на чтение некоторых файлов (например, журналов), что полезно, но это зависит от проекта.
Кенорб

Я вижу, что это работает, я автоматически вошел в систему как пользователь, но я все еще генерирую файлы, принадлежащие пользователю root. Я даже просто использовал «USER user», поскольку мое имя пользователя в локальном пользователе и группе - «user». Все еще генерирует файлы, принадлежащие корню. Есть ли что-то еще, что я должен делать? Я в основном делаю Docker-контейнер, который компилирует нашу кодовую базу. Поэтому он проверяет код из SVN, устанавливает переменные, используя исходный код Bash. Могут ли команды bash работать с правами root, даже если меня никогда не спрашивают пароль 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 username ---> Запуск в db9fd22d469d Параметр s является неоднозначным (shell, system) adduser [--home DIR] [--shell SHELL] [--no-create -home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID] [--disabled-пароль] [--disabled-login] [--encrypt-home] ПОЛЬЗОВАТЕЛЬ Добавить обычного пользователя
обучение

9

Вы можете имитировать Dockerfile с открытым исходным кодом, например:

Узел: узел 12-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

Я думаю, что это хороший способ следовать открытым исходным кодом.


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если вам действительно нужно.


Частичный кредит: ответ Райана М


1

В качестве альтернативы вы можете сделать это.

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

Первая команда создает группу под названием demo . Вторая команда создает демо- пользователя и добавляет его в ранее созданную демо- группу.

Флаги означает:

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.