プログラミング初心者がアーキテクトっぽく語る

見苦しい記事も多数あるとは思いますが訂正しつつブログと共に成長していければと思います

RUN、ENTRYPOINT、CMDのexec表記とshell表記

前回、dockerfileのENTRYPOINTとCMDについて紹介した。

architecting.hateblo.jp

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が終了するとコンテナが終了する。
    • 本来実行したいことが完了する前にコンテナが終了しては困る。