Запуск приложения внутри Докер как не-root пользователя
после вчерашние новости шокера, похоже, что приложения внутри контейнера Docker не должны запускаться как root. Я пытался обновить мой Dockerfile
чтобы создать пользователя приложения, однако изменение разрешений на файлы приложений (в то время как все еще root), похоже, не работает. Я предполагаю, что это связано с тем, что некоторые разрешения LXC не предоставляются пользователю root, возможно?
вот мой Dockerfile:
# Node.js app Docker file
FROM dockerfile/nodejs
MAINTAINER Thom Nichols "thom@thomnichols.org"
RUN useradd -ms /bin/bash node
ADD . /data
# This next line doesn't seem to have any effect:
RUN chown -R node /data
ENV HOME /home/node
USER node
RUN cd /data && npm install
EXPOSE 8888
WORKDIR /data
CMD ["npm", "start"]
довольно просто, но когда я ls -l
все все еще принадлежит root:
[ node@ed7ae33e76e1:/data {docker-nonroot-user} ]$ ls -l /data
total 64K
-rw-r--r-- 1 root root 383 Jun 18 20:32 Dockerfile
-rw-r--r-- 1 root root 862 Jun 18 16:23 Gruntfile.js
-rw-r--r-- 1 root root 1.2K Jun 18 15:48 README.md
drwxr-xr-x 4 root root 4.0K May 30 14:24 assets/
-rw-r--r-- 1 root root 416 Jun 3 14:22 bower.json
-rw-r--r-- 1 root root 930 May 30 01:50 config.js
drwxr-xr-x 4 root root 4.0K Jun 18 16:08 lib/
drwxr-xr-x 42 root root 4.0K Jun 18 16:04 node_modules/
-rw-r--r-- 1 root root 2.0K Jun 18 16:04 package.json
-rw-r--r-- 1 root root 118 May 30 18:35 server.js
drwxr-xr-x 3 root root 4.0K May 30 02:17 static/
drwxr-xr-x 3 root root 4.0K Jun 18 20:13 test/
drwxr-xr-x 3 root root 4.0K Jun 3 17:38 views/
мой обновленный dockerfile отлично работает благодаря разъяснению @creak о том, как работают Тома. Как только начальные файлы chown
Эд npm install
выполняется от имени пользователя, не являющегося пользователем root. И благодаря postinstall
крюк, НПМ работает bower install && grunt assets
который заботится о оставшихся шагах установки и избегает любой необходимости npm install -g
любые инструменты cli узла, такие как bower, grunt или coffeescript.
5 ответов:
Это немного сложнее, на самом деле из-за изображения начинаются от.
Если вы смотреть на источник, вы заметите, что
/data/
- Это объем. Так что все, что вы делаете вDockerfile
будет отброшен и переопределен во время выполнения Томом, который затем монтируется.вы можете chown во время выполнения, изменив свой CMD на что-то вроде
CMD chown -R node /data && npm start
.
проверьте это сообщение:http://www.yegor256.com/2014/08/29/docker-non-root.html In rultor.com мы запускаем все сборки в их собственных контейнерах Docker. И каждый раз перед запуском скриптов внутри контейнера, мы переключаемся на не-root пользователей. Вот как:
adduser --disabled-password --gecos '' r adduser r sudo echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers su -m r -c /home/r/script.sh
r
это пользователь, которого мы используем.
обновление 2015-09-28
Я заметил, что этот пост получает немного внимания. Один совет для тех, кто потенциально заинтересован в том, чтобы сделать что-то подобное. Я попытаюсь использовать Python или другой язык в качестве оболочки для выполнения скрипта. Выполнение собственных сценариев bash у меня были проблемы при попытке передать различные аргументы в мои контейнеры. В частности, были проблемы с интерпретацией / экранированием символов "и" ракушка.
мне нужно было изменить пользователя по немного другой причине.
Я создал Docker-образ расквартировывать полнофункциональную установку ImageMagick и Ffmpeg С желанием, чтобы я мог делать преобразования на изображениях/видео в моей ОС хоста. Моя проблема заключалась в том, что это инструменты командной строки, поэтому немного сложнее выполнить их через docker, а затем получить результаты обратно в ОС хоста. Я справился для этого необходимо установить том docker. Это, казалось, работало нормально, за исключением того, что выход изображения/видео выходил как принадлежащий root (т. е. пользователь контейнер docker был запущен как), а не пользователь, который выполнил команду.
Я посмотрел на подход, который @François Zaninotto упомянул в своем ответ (вы можете увидеть полный сценарий make здесь). Это было действительно круто, но я предпочел вариант создания bash сценарий оболочки, который я затем зарегистрирую на своем пути. Я взял некоторые концепции из подхода Makefile (в частности, создание пользователя/группы), а затем создал сценарий оболочки.
вот пример моего dockermagick shell-скрипт:
#!/bin/bash ### VARIABLES DOCKER_IMAGE='acleancoder/imagemagick-full:latest' CONTAINER_USERNAME='dummy' CONTAINER_GROUPNAME='dummy' HOMEDIR='/home/'$CONTAINER_USERNAME GROUP_ID=$(id -g) USER_ID=$(id -u) ### FUNCTIONS create_user_cmd() { echo \ groupadd -f -g $GROUP_ID $CONTAINER_GROUPNAME '&&' \ useradd -u $USER_ID -g $CONTAINER_GROUPNAME $CONTAINER_USERNAME '&&' \ mkdir --parent $HOMEDIR '&&' \ chown -R $CONTAINER_USERNAME:$CONTAINER_GROUPNAME $HOMEDIR } execute_as_cmd() { echo \ sudo -u $CONTAINER_USERNAME HOME=$HOMEDIR } full_container_cmd() { echo "'$(create_user_cmd) && $(execute_as_cmd) $@'" } ### MAIN eval docker run \ --rm=true \ -a stdout \ -v $(pwd):$HOMEDIR \ -w $HOMEDIR \ $DOCKER_IMAGE \ /bin/bash -ci $(full_container_cmd $@)
этот скрипт привязан к изображению' acleancoder/imagemagick-full', но это можно изменить, отредактировав переменную в верхней части скрипта.
что он в основном делает это:
- создайте идентификатор пользователя и группу в контейнер чтобы соответствовать пользователю, который выполняет скрипт от хоста.
- установить текущий рабочий каталог хоста (используя Тома докера) в домашний каталог для пользователей, мы создаем в рамках выполнения докер контейнер.
- задает каталог tmp в качестве рабочего каталога контейнер.
- передает любые аргументы, которые передаются в скрипт, который потом будет исполняться ' / bin / bash на выполнение докер контейнер.
теперь я могу запустить ImageMagick / Ffmpeg команды против файлов на хост-ОС. Например, скажем, я хочу преобразовать изображение MyImage.в формате JPEG на PNG файл, теперь я могу сделать следующее:
$ cd ~/MyImages $ ls MyImage.jpeg $ dockermagick convert MyImage.jpeg Foo.png $ ls Foo.png MyImage.jpeg
Я также подключился к "stdout", чтобы я мог запустить команду ImageMagick identify, чтобы получить информацию об изображении на моем хосте, например:
$ dockermagick identify MyImage.jpeg MyImage.jpeg JPEG 640x426 640x426+0+0 8-bit DirectClass 78.6KB 0.000u 0:00.000
существует очевидная опасность монтирования текущего каталога и разрешения передачи любого произвольного определения команды для выполнения. Но есть также много способов сделать скрипт более безопасным / безопасным. Я выполняю это в своей собственной непроизводственной личной среде, поэтому они не имеют самое большое беспокойство за меня. Но я настоятельно рекомендую вам принять во внимание опасности, если вы решите расширить этот сценарий. Также стоит упомянуть, что этот скрипт не учитывает хост OS X. Элемент файл то, что я краду идеи/концепции, учитывает это, поэтому вы можете расширить этот скрипт для этого.
еще одно ограничение, чтобы отметить, что я могу ссылаться только на файлы в настоящее время в пути, для которого я выполняю сценарий. Это связано с тем, как я монтирую Тома, поэтому следующее не будет работать:
$ cd ~/MyImages $ ls MyImage.jpeg $ dockermagick convert ~/DifferentDirectory/AnotherImage.jpeg Foo.png $ ls MyImage.jpeg
лучше всего просто перейти в каталог, содержащий изображение, и выполнить его непосредственно. Конечно, я уверен, что есть способы обойти это ограничение тоже, но для меня и моих текущих потребностей, это будет делать.
Примечание:я отвечаю здесь, потому что, учитывая общее название, этот вопрос появляется в google, когда вы ищете решение для "запуска приложения внутри Docker как некорневого пользователя". Надеюсь, это поможет тем, кто застрял здесь.
С альпийские Linux вы можете создать системного пользователя, как это:
RUN adduser -D -H -S -s /bin/false -u 1000 myuser
все
Dockerfile
после этой строки выполняется сmyuser
.
myuser
пользователь имеет:
- без пароля
- нет дома реж
- нет оболочки входа в систему
- нет root открыть.
это
adduser --help
:-h DIR Home directory -g GECOS GECOS field -s SHELL Login shell -G GRP Add user to existing group -S Create a system user -D Don't assign a password -H Don't create home directory -u UID User id -k SKEL Skeleton directory (/etc/skel)
Примечание:этот ответ дается, потому что многие люди, ищущие некорневое использование, окажутся здесь. Будьте осторожны, это не решает проблему, которая вызвала проблему, но обращается к заголовку и разъяснению к ответу, данному @yegor256, который использует пользователя без root внутри контейнера. Этот ответ объясняет, как это сделать для не-debian/не-ubuntu use-case. Это не решает проблему с объемами.
на системах на основе Red Hat, такие как Fedora и CentOS, это можно сделать следующим образом:
RUN adduser user && \ echo "user ALL=(root) NOPASSWD:ALL" | tee -a /etc/sudoers.d/user && \ chmod 0440 /etc/sudoers.d/user
в вашем Dockerfile вы можете запускать команды от имени этого пользователя, выполнив:
RUN su - user -c "echo Hello $HOME"
и команда может быть выполнена как:
CMD ["su","-","user","-c","/bin/bash"]
пример этого можно найти здесь: https://github.com/gbraad/docker-dev/commit/644c51002f4b8e6fe5bb745638542a4c3d908b16