こんにちは。Яeiです。
今回は、現役エンジニアの私がDockerfileのUSERの書き方について記事にしようと思います。
USERはLinuxのユーザ、グループの概念が分かっていればさほど難しいものではありません。
当記事ではLinuxのユーザ、グループの話をおさらいしながらUSER命令について解説致します。
当記事は以下の公式リファレンスを元に記載しております。
Dockerfile reference >>
目次
結論:USERの書き方
書き方は以下となります。
USER <user>[:<group>]
または
USER <UID>[:<GID>]
DockerfileでUSER指定した後のRUN、ENTRYPOINT、CMDの実行はこのユーザ、グループにて実行される。
詳細:USERの書き方
前提知識(ユーザとグループ)
Linuxでは複数の人が同じサーバで作業を実施するため、ユーザの管理が重要になってきます。
例えば、私の場合はreiというユーザを作成してもらい、reiユーザでLinuxにログインして作業するイメージです。
例えば、rei1、rei2、rei3というユーザを追加した場合、Linuxでは以下のようにホームディレクトリ配下に専用ディレクトリが作成され、作業を行う形になります。
# ls -ltr
total 12
drwxr-xr-x 2 rei1 rei1 4096 Oct 15 09:49 rei1
drwxr-xr-x 2 rei2 rei2 4096 Oct 15 09:49 rei2
drwxr-xr-x 2 rei3 rei3 4096 Oct 15 09:49 rei3
rei1さんが作業中にうっかりrei2さんのディレクトリを更新しようとすると以下のように権限エラーになります。
$ touch test.log ../rei2/
touch: setting times of '../rei2/': Permission denied
さて、ユーザについてもう一つ覚えておいてほしいのが、rootユーザになります。
このユーザはすべての権限を与えられた特別なユーザになります。
そのため、先の例ですとrei1さんのディレクトリもrei2さんのディレクトリも操作可能となります。
もちろん、その他の一般的なユーザでは触れないような重要ファイルにもアクセスすることができるので。
次に、グループについてです。
先ほどの例で、rei1さんとrei2さんとrei3さんとで同じ共有ディレクトリを欲しい場合があります。
その場合、同じグループにrei1さんとrei2さんとrei3さんを含めておいて、共有したいディレクトリにこのグループの権限を付与しておきます。
すると、共有ディレクトリで作業することも可能となります。
例えば、testグループを作成します。
# addgroup test
Adding group `test' (GID 1004) ...
Done.
次に、各ユーザをこのグループに含めます(例えば以下のようなコマンド)。
# adduser rei1 test
Adding user `rei1' to group `test' ...
Adding user rei1 to group test
Done.
testグループに所属するユーザを確認してみます。
# getent group test
test:x:1004:rei1,rei2,rei3
さて、この状態で、共有ディレクトリworkを作成し、testグループに所属グループを変更し、書き込み権限を与えてあげましょう。
# chown -R :test work/
# ls -ltr
drwxr-xr-x 2 rei2 rei2 4096 Oct 15 09:49 rei2
drwxr-xr-x 2 rei3 rei3 4096 Oct 15 09:49 rei3
drwxr-xr-x 2 root test 4096 Oct 15 09:54 work
drwxr-xr-x 1 rei1 rei1 4096 Oct 15 10:21 rei1
# chmod g+sw work/
# ls -ltr
drwxr-xr-x 2 rei2 rei2 4096 Oct 15 09:49 rei2
drwxr-xr-x 2 rei3 rei3 4096 Oct 15 09:49 rei3
drwxrwxr-x 2 root test 4096 Oct 15 09:54 work
drwxr-xr-x 1 rei1 rei1 4096 Oct 15 10:21 rei1
この状態で試しにrootユーザでファイルを作成し、testグループも書き込み可能になるように権限を与えてあげます。
# echo "test" > root.log
# chmod g+w root.log
するとrei1ユーザでもrei2ユーザでもwork配下に書き込みが可能となります。
$ echo "test1" >> work/root.log
$ echo "test2" >> work/root.log
$ cat root.log
test
test1
test2
今回はかなり簡易的な説明になりましたが、Linuxにおけるユーザやグループについてはこのようなイメージになります。
USERの使い方
USER <user>[:<group>]
または
USER <UID>[:<GID>]
DockerfileではRUNやENTRYPOINT、CMD、で実行されるユーザはrootユーザになります。
まず、USER指定をしない場合、rootユーザで実行されます。例えば以下のようなDockerfileでみてみます。
FROM nginx:latest
RUN whoami
この状態でイメージビルドすると以下のような結果になります。
docker image build --progress plain . -t test --no-cache
略
#5 [2/2] RUN whoami
#5 sha256:c5289497f1b3f574427a316bdae66aa2a4d533b09b7de9142346f98e2d57974a
#5 0.270 root
#5 DONE 0.3s
略
USER指定していないため、woamiコマンドの結果はrootとなります。
次に、以下のようにUSER指定した場合はどうなるでしょうか。
FROM nginx:latest
RUN adduser rei
USER rei
RUN whoami
結果は以下のように追加したユーザで実行されます。
#6 [3/3] RUN whoami
#6 sha256:29db1c61dae4cdab1542d778eeefe32f1a196f58816c41f34be2024a1e9e6f8b
#6 0.386 rei
#6 DONE 0.4s
ユーザとかグループの概念が分かっている方は特に難しいことはないですね。
ベースイメージでUSER指定されている場合
最後に、ベースイメージでUSER指定されている場合にどうなるのか見てみましょう。
以下のDockerfile1で作成されるイメージをベースイメージとして、Dockerfile2の場合で実験してみます。
FROM nginx:latest
RUN adduser rei
USER rei
RUN whoami
Dockerfile2
FROM test:latest
RUN whoami
結果は以下のようになりました。
#5 [2/2] RUN whoami
#5 sha256:06cf4336a2858c71310e9301ebd0064db830f042f9395bde46b0b5aa22fbfcc9
#5 0.327 rei
#5 DONE 0.3s
つまり、最後にUSERで指定されたユーザが採用されるわけです。
これはベースとしているイメージで設定されている場合も含みます。
そのため、ベースイメージで指定されているUSER設定も意識しておくと良さそうですね。
当記事は以上となります。
USER命令はLinuxのユーザやグループを理解されている方にとってはとてもしっくりくる命令だったと思います。
長々とお疲れさまでした。