RUN、ENTRYPOINT、CMDのexec表記とshell表記
前回、dockerfileのENTRYPOINTとCMDについて紹介した。
RUN、ENTRYPOINT、CMDにはexec表記とshell表記の2つの記法がある。
以降、CMDを例にして2つの記法について見ていく。
shell表記
- shell表記で記述した例を示す。
CMD echo hi
- shell表記を使用すると「/bin/sh -c」が起動し、そのシェル上で指定したコマンド(echo hi)が実行される
- シェル機能を利用できることがメリット
- 環境変数の置き換え($HOME → /home/user1)
- パイプやリダイレクト
- 「/bin/sh -c」がRoot Processになる
- 指定したコマンドはPID 2になる
exec表記
- exec表記で記述した例を示す。
CMD [ "echo", "hi" ]
- exec表記を使用すると「/bin/sh -c」は起動せず、直接、指定したコマンド(echo hi)が実行される
- exec表記ではシェル機能は利用できない
- []はJSON配列である
- 配列の要素はダブルクオテーションで囲わなくてはならない
- 配列の最初の要素はExecutableでなくてはならない
- CMD [ "echo hi" ]はNG
- 指定したコマンド(echo hi)がRoot Processになる
Best Practice
結論
- 基本的にはexec表記を使用する
- シェルの機能が必須であればshell表記を使用する
exec表記が推奨される理由
- exec表記はシェルを実行しないのでリソースを節約できる
- exec表記で指定したプロセスはRoot Processになる(注)
注
Root Processは以下のような特性があるためどのプロセスがRoot Processになるかは重要である。
- Root Processはdocker stop時にシグナルを受け取る。
- 終了時の処理を記述したプログラムがあればそのプログラムをRoot Processにしたい。
- Root Processが終了するとコンテナが終了する。
- 本来実行したいことが完了する前にコンテナが終了しては困る。