Docker: выполнение всех команд как локальный пользователь, а не как root - PullRequest
0 голосов
/ 07 февраля 2019

Как запустить команды docker run и docker-compose up/run, чтобы процесс внутри докера выполнялся пользователем с тем же uuid, что и у моего локального пользователя?

Мне нужно сделать это такчто любые файлы, сгенерированные процессом "inside-docker", будут иметь права владения моего локального пользователя.

Для репликации:

Используйте контейнер alpine: 3.9 , смонтируйте том для записи и создайте файл.Предположим, что мое текущее имя пользователя user.

mkdir output_dir #Create an output directory
docker run -it --rm --volume "/path/to/output_dir:/tmp" alpine:3.9 touch /tmp/file.txt
ls -la output_dir/file.txt

выдаст:

-rw-r--r-- 1 root root 0 Feb  7 19:51 /path/to/output_dir/file.txt

Это означает, что мне нужно sudo chown user:user /path/to/output_dir/file.txt, чтобы иметь доступ в качестве текущего пользователя самостоятельнофайловая система.

Как мне сделать это без этого дополнительного шага?

Идея, которая приходит на ум:

Добавить Docker Entrypoint , который создастпользователь внутри контейнера с тем же uuid, что и мой локальный пользователь, и выполнить любой код от имени этого пользователя.

docker-entrypoint.sh

#!/bin/sh
TEMP_UID="${TEMP_UID:-1000}"
set -ux
useradd -s /bin/false --no-create-home -u ${TEMP_UID} temp
#su-exec is an executable which makes it easy to run a process as a specific user.
exec su-exec temp $@

проблема в том, что мне придется вводить TEMP_UID=<user_id> в качестве переменной среды в каждую команду docker run или включать в мой файл docker-compose.yml для каждой команды docker-compose up/run.Если у Docker есть внутренняя переменная, которая отслеживает uuid пользователя, который ее запустил, я бы просто использовал это.Но я не могу найти такую ​​внутреннюю переменную.

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Многие текущие параметры требуют изменения вне контейнера для передачи текущего пользователя или использования переменных, которые могут существовать не во всех средах.Мое предпочтительное решение, так как цель состоит в том, чтобы установить права доступа к файлам на смонтированных томах, - это запустить точку входа как root с помощью скрипта, который изменяет идентификатор пользователя контейнера в соответствии с идентификатором имени подключения тома.А затем конец точки входа запускает приложение с exec gosu $app_user_name "$@" для переключения с пользователя root на того пользователя приложения, который был изменен внутри контейнера.

Сценарии для этого находятся в моем репозитории базовых изображений.Обратите внимание на сценарий fix-perms, который включает в себя два раздела, таких как следующий (один для uid и другой для gid):

# update the uid
if [ -n "$opt_u" ]; then
  OLD_UID=$(getent passwd "${opt_u}" | cut -f3 -d:)
  NEW_UID=$(stat -c "%u" "$1")
  if [ "$OLD_UID" != "$NEW_UID" ]; then
    echo "Changing UID of $opt_u from $OLD_UID to $NEW_UID"
    usermod -u "$NEW_UID" -o "$opt_u"
    if [ -n "$opt_r" ]; then
      find / -xdev -user "$OLD_UID" -exec chown -h "$opt_u" {} \;
    fi
  fi
fi

Значение OLD_UID берется из идентификатора пользователя в изображении, а NEW_UID - изобъемное крепление.Если они не совпадают, запускается команда usermod, а затем рекурсивная команда chown для исправления любых файлов со старым uid / gid.

Обратите внимание, что в работе, где идентификатор пользователя находится нахост может быть стандартизирован, я сопоставляю идентификатор пользователя хоста с идентификатором изображения, если требуется том, что позволяет мне запускать точку входа в качестве этого пользователя вместо пользователя root.Точка входа проверяет текущий идентификатор пользователя и пропускает сценарий fix-perms и команду gosu, если он не является пользователем root.

0 голосов
/ 08 февраля 2019

Я думаю, что ответ так же прост, как

docker run --user ${UID} -it --rm --volume "/path/to/output_dir:/tmp" alpine:3.9 touch /tmp/file.txt

Заметьте, я ввел --user ${UID} в ваш пример команды.

...