Як додати користувачів до контейнера Docker?


285

У мене є контейнер для докера з деякими процесами (uwsgi та селера), що працюють всередині. Я хочу створити користувача селери та користувача 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

у ваш dockerfile. Після цього кожна команда, а також інтерактивні сеанси виконуватимуться як користувач newuser:

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

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

Використання непривілейованих користувачів всередині контейнерів є хорошою ідеєю з міркувань безпеки. Він також має кілька недоліків. Найголовніше, що люди, які отримують зображення з вашого зображення, повинні буде переключитися назад на корінь, перш ніж вони зможуть виконувати команди з привілеями суперрусера.


142
Я рекомендую використовувати параметри повного імені в 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 foundalpine linux
deathangel908

91

Щоб уникнути інтерактивних питань аддусера, ви можете зателефонувати йому за цими параметрами:

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

--gecosПараметр використовується для установки додаткової інформації. У цьому випадку він просто порожній.

У системах із зайнятим ящиком (наприклад, Alpine) використовуйте

RUN adduser -D -g '' newuser

Див. Аддусер зайнятої скриньки


3
Дякую! Схоже, adduserрішення високого рівня, як правило, віддають перевагу використанню функцій низького рівня, таких як useradd.
ахмед

adduser: unrecognized option: gecosЦе, здається, не працює на Альпійському.
weberc2

що робить --disabled-password і як ми можемо встановити пароль одночасно в Dockerfile?
Hossein

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: Зв'язування Dockerfile .


2
Чому користувач потрапить у кореневу групу? Чи не вся суть у цьому полягає в тому, щоб
некористувацького

5
@Novaterata Залежно від використання. rootГрупа не вказує, що вони мають кореневий доступ, просто вони мають більше доступу до читання файлів (наприклад, журналів), що корисно, але це залежить від проекту.
kenorb

Я бачу, що це працює, я автоматично входжу як користувач, але все одно генерую файли, що належать root. Я навіть просто використовував "USER user", оскільки моє ім'я користувача для локального користувача та групи є "user". Досі генерує файли, що належать кореням. Чи є ще щось, що я повинен робити? Я в основному створюю контейнер докера, який компілює нашу кодову базу. Так він перевіряє код із svn, встановлює змінні за допомогою джерела bash. Чи можуть команди bash виконувати функції root, навіть якщо мене ніколи не запитують пароль root?
JoeManiaci

14

Додавання користувача в докер і запуск вашого додатка під цим користувачем є дуже хорошою практикою з точки зору безпеки. Для цього я рекомендую наступні кроки:

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 Опція s неоднозначна (оболонка, система) adduser [--home DIR] [--shell SHELL] [--no-create -home] [- 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якщо вам це справді потрібно.


Частковий кредит: відповідь Райана М


1

Або ви можете зробити так.

RUN addgroup demo && adduser -DH -G 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.