Docker 내에서 루트가 아닌 사용자로 앱 실행
어제 Shocker 소식 이후 Docker 컨테이너 내부의 앱이 루트로 실행되어서는 안되는 것 같습니다. Dockerfile
앱 사용자를 만들기 위해 업데이트를 시도했지만 앱 파일에 대한 권한 변경 (아직 루트 인 동안)이 작동하지 않는 것 같습니다. 아마도 루트 사용자에게 일부 LXC 권한이 부여되지 않았기 때문이라고 생각합니다.
내 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
모든 것을 여전히 루트가 소유하고 있을 때 :
[ 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
루트가 아닌 사용자로 실행됩니다. postinstall
후크 덕분에 npm이 실행 bower install && grunt assets
되어 나머지 설치 단계를 처리하고 npm install -g
bower, grunt 또는 coffeescript와 같은 노드 CLI 도구 가 필요하지 않습니다 .
이것은 약간 까다 롭습니다. 실제로 시작하는 이미지 때문입니다.
소스 를 보면/data/
볼륨이 있음을 알 수 있습니다. 따라서에서 수행하는 모든 작업은 Dockerfile
실행시 마운트 된 볼륨에 의해 무시되고 무시됩니다.
CMD를 다음과 같이 변경하여 런타임에 chown 할 수 있습니다 CMD chown -R node /data && npm start
.
이 게시물을 확인하십시오. http://www.yegor256.com/2014/08/29/docker-non-root.html rultor.com 에서는 모든 빌드를 자체 Docker 컨테이너에서 실행합니다. 컨테이너 내에서 스크립트를 실행하기 전에 항상 루트가 아닌 사용자로 전환합니다. 방법은 다음과 같습니다.
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 스크립트를 수행하는 동안 다양한 인수를 컨테이너에 전달하려고 할 때 문제가 발생했습니다. 특히 셸에서 "및 '문자를 해석 / 이스케이프하는 데 문제가있었습니다.
약간 다른 이유로 사용자를 변경해야했습니다.
호스트 OS 내에서 이미지 / 비디오를 변환 할 수 있기를 바라 면서 ImageMagick 및 Ffmpeg 의 전체 기능 설치를 포함 하는 도커 이미지를 만들었습니다 . 내 문제는 이것이 명령 줄 도구이므로 도커를 통해 실행 한 다음 결과를 호스트 OS로 다시 가져 오는 것이 약간 까다 롭다는 것입니다. 나는 도커 볼륨을 장착하여 이것을 허용했습니다. 이것은 이미지 / 비디오 출력이 명령을 실행 한 사용자가 아닌 루트 (즉, 도커 컨테이너가 실행중인 사용자) 가 소유 한 것으로 나오는 것을 제외하고는 정상적으로 작동하는 것처럼 보였습니다 .
@ François Zaninotto가 그의 답변 에서 언급 한 접근 방식을 살펴 보았습니다 ( 여기 에서 전체 make 스크립트를 볼 수 있습니다 ). 정말 멋졌지만 내 경로에 등록 할 bash 셸 스크립트를 만드는 옵션을 선호했습니다. Makefile 접근법 (특히 사용자 / 그룹 생성)에서 몇 가지 개념을 취한 다음 쉘 스크립트를 생성했습니다.
다음은 내 dockermagick 셸 스크립트 의 예입니다 .
#!/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'이미지에 바인딩되어 있지만 스크립트 상단의 변수를 편집하여 변경할 수 있습니다.
기본적으로하는 일은 다음과 같습니다.
- 호스트 OS 에서 스크립트를 실행하는 사용자와 일치하도록 컨테이너 내에 사용자 ID와 그룹을 만듭니다 .
- Mounts the current working directory of the host OS (using docker volumes) into home directory for the user we create within the executing docker container.
- Sets the tmp directory as the working directory for the container.
- Passes any arguments that are passed to the script, which will then be executed by the '/bin/bash' of the executing docker container.
Now I am able to run the ImageMagick/Ffmpeg commands against files on my host OS. For example, say I want to convert an image MyImage.jpeg into a PNG file, I could now do the following:
$ cd ~/MyImages
$ ls
MyImage.jpeg
$ dockermagick convert MyImage.jpeg Foo.png
$ ls
Foo.png MyImage.jpeg
I have also attached to the 'stdout' so I could run the ImageMagick identify command to get info on an image on my host, for e.g.:
$ dockermagick identify MyImage.jpeg
MyImage.jpeg JPEG 640x426 640x426+0+0 8-bit DirectClass 78.6KB 0.000u 0:00.000
There are obvious dangers about mounting the current directory and allowing any arbitrary command definition to be passed along for execution. But there are also many ways to make the script more safe/secure. I am executing this in my own non-production personal environment, so these are not of highest concern for me. But I would highly recommend you take the dangers into consideration should you choose to expand upon this script. It's also worth me mentioning that this script doesn't take an OS X host into consideration. The make file that I steal ideas/concepts from does take this into account, so you could extend this script to do so.
Another limitation to note is that I can only refer to files currently in the path for which I am executing the script. This is because of the way I am mounting the volumes, so the following would not work:
$ cd ~/MyImages
$ ls
MyImage.jpeg
$ dockermagick convert ~/DifferentDirectory/AnotherImage.jpeg Foo.png
$ ls
MyImage.jpeg
It's best just to go to the directory containing the image and execute against it directly. Of course I am sure there are ways to get around this limitation too, but for me and my current needs, this will do.
Note: I answer here because, given the generic title, this Question pops up in google when you look for a solution to "Running app inside Docker as non-root user". Hope it helps those who are stranded here.
With Alpine Linux you can create a system user like this:
RUN adduser -D -H -S -s /bin/false -u 1000 myuser
Everything in the Dockerfile
after this line is executed with myuser
.
myuser
user has:
- no password assigned
- no home dir
- no login shell
- no root access.
This is from 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)
Note: This answer is given because many people looking for non-root usage will end up here. Beware, this does not address the issue that caused the problem, but is addressing the title and clarification to an answer given by @yegor256, which uses a non-root user inside the container. This answer explains how to accomplish this for non-debian/non-ubuntu use-case. This is not addressing the issue with volumes.
On Red Hat-based systems, such as Fedora and CentOS, this can be done in the following way:
RUN adduser user && \
echo "user ALL=(root) NOPASSWD:ALL" | tee -a /etc/sudoers.d/user && \
chmod 0440 /etc/sudoers.d/user
In your Dockerfile you can run commands as this user by doing:
RUN su - user -c "echo Hello $HOME"
And the command can be run as:
CMD ["su","-","user","-c","/bin/bash"]
An example of this can be found here: https://github.com/gbraad/docker-dev/commit/644c51002f4b8e6fe5bb745638542a4c3d908b16
참고URL : https://stackoverflow.com/questions/24308760/running-app-inside-docker-as-non-root-user
'developer tip' 카테고리의 다른 글
Jupyter / iPython에서 플롯을 동적으로 업데이트하는 현재 올바른 방법은 무엇입니까? (0) | 2020.10.22 |
---|---|
IIS 7에서 "통과 인증"이란 무엇입니까? (0) | 2020.10.22 |
Docker 네트워킹-nginx : [emerg] 호스트를 업스트림에서 찾을 수 없음 (0) | 2020.10.22 |
주어진 Lat Lng 위치에서 특정 거리 내에있는 모든 Latitude Longitude 위치를 찾는 알고리즘 (0) | 2020.10.22 |
TypeScript를 축소 된 코드로 컴파일 할 수 있습니까? (0) | 2020.10.22 |