昨日のShockerのニュース の後、Dockerコンテナ内のアプリをrootとして実行すべきではないようです。 Dockerfile
を更新してアプリユーザーを作成しようとしましたが、アプリファイルのアクセス許可を(まだrootに)変更しても機能しないようです。これは、おそらくLXCアクセス許可がルートユーザーに付与されていないためだと思いますか?
これが私のDockerfileです。
# Node.js app Docker file
FROM dockerfile/nodejs
MAINTAINER Thom Nichols "[email protected]"
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
edになると、npm install
が非rootユーザーとして実行されます。 postinstall
フックのおかげで、npmはbower install && grunt assets
を実行し、残りのインストール手順を処理し、npm install -g
bower、grunt、coffeescriptなどのノードcliツールの必要性を回避します。
これは少し注意が必要です。実際には、元のイメージが原因です。
ソースを見る の場合、/data/
はボリュームであることがわかります。したがって、Dockerfile
で行うすべての操作は破棄され、実行時にマウントされたボリュームによってオーバーライドされます。
CMDをCMD chown -R node /data && npm start
のようなものに変更することにより、実行時にchownできます。
この投稿を確認してください: 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 imageを作成しましたImageMagickとFfmpegのフル機能インストールを収容し、ホスト内の画像/ビデオの変換を行えるようにしたいOS。私の問題は、これらがコマンドラインツールであるため、ドッカーを介して実行し、結果をホストOSに戻すのが少し難しいことです。 Dockerボリュームをマウントすることでこれを可能にしました。これは、コマンドを実行したユーザーではなく、イメージ/ビデオ出力がroot(つまり、Dockerコンテナーを実行しているユーザー)によって所有されているとして出力されることを除いて、正常に機能するように見えました。
@FrançoisZaninottoが answer (完全なmakeスクリプト here で見ることができます)で言及しているアプローチを見ました。とてもクールでしたが、bash Shellスクリプトを作成して、パスに登録するオプションを選びました。 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」画像にバインドされていますが、スクリプトの上部にある変数を編集することで変更できます。
それが基本的にすることは:
これで、ホストOS上のファイルに対してImageMagick/Ffmpegコマンドを実行できるようになりました。たとえば、画像MyImage.jpegをPNGファイルに変換したい場合、次のようにできます。
$ cd ~/MyImages
$ ls
MyImage.jpeg
$ dockermagick convert MyImage.jpeg Foo.png
$ ls
Foo.png MyImage.jpeg
また、「stdout」にアタッチして、ImageMagick識別コマンドを実行して、ホスト上の画像に関する情報を取得できるようにしました。例:
$ dockermagick identify MyImage.jpeg
MyImage.jpeg JPEG 640x426 640x426+0+0 8-bit DirectClass 78.6KB 0.000u 0:00.000
現在のディレクトリをマウントし、実行のために任意のコマンド定義を渡すことを許可することには明らかな危険があります。しかし、スクリプトをより安全/安全にするための多くの方法もあります。私はこれを自分の非生産的な個人環境で実行しているので、これらは私にとって最大の関心事ではありません。ただし、このスクリプトを拡張する場合は、危険性を考慮することを強くお勧めします。また、このスクリプトはOS Xホストを考慮に入れていないことを言及する価値があります。 make file 私がアイデア/概念を盗むのはこれを考慮に入れているので、このスクリプトを拡張することができます。
注意すべきもう1つの制限は、スクリプトを実行しているパスに現在あるファイルのみを参照できることです。これは、ボリュームをマウントする方法が原因であるため、以下は機能しません。
$ cd ~/MyImages
$ ls
MyImage.jpeg
$ dockermagick convert ~/DifferentDirectory/AnotherImage.jpeg Foo.png
$ ls
MyImage.jpeg
イメージを含むディレクトリに移動して、それに対して直接実行することをお勧めします。もちろん、この制限を回避する方法もあると確信していますが、私と現在のニーズについては、これで十分です。
注:「Docker内で非ルートとしてアプリを実行する」という解決策を探すと、一般的なタイトルが与えられ、この質問がGoogleにポップアップ表示されるため、ここで答えますユーザー"。ここで立ち往生している人々を助けることを願っています。
Alpine Linuxを使用すると、次のようなシステムユーザーを作成できます。
RUN adduser -D -H -S -s /bin/false -u 1000 myuser
この行の後のDockerfile
内のすべてがmyuser
で実行されます。
myuser
ユーザーが持っているもの:
これは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)
注:この答えは、ルート以外の使用を探している多くの人々がここで終わるために与えられます。注意してください、これは問題の原因となった問題には対処していませんが、コンテナ内で非rootユーザーを使用する@ yegor256によって与えられた回答のタイトルと説明に対処しています。この回答では、debian/ubuntu以外のユースケースでこれを実現する方法について説明しています。これは、ボリュームの問題に対処していません。
FedoraやCentOSなどのRed Hatベースのシステムでは、次の方法でこれを実行できます。
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