コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

Dockerfile内のENTRYPOINTとCMD(とRUN) の使い分け

人に説明するためにざっくりまとめる。

環境

$ docker -v
Docker version 18.06.1-ce, build e68fc7a

分類

コマンド名 説明
RUN Shellの実行をするコマンド
ENTRYPOINT docker run 実行時に行われるコマンド
CMD 『ENTRYPOINTが未指定、かつ docuker run で何も指定されなかったときに実行されるコマンド』あるいは『ENTRYPOINT指定地に何も指定しなかった場合の引数』
  1. ENTRYPOINTが指定されていれば引数のコマンドを後ろにつける、無ければCMDを後ろにつける
  2. ENTRYPOINTがなければ引数のコマンドを実行する、引数コマンドがなければCMDを実行する

みたいな流れなんですが、わかりにくいので例をあげる

共通事項として、Dockerfileを作って、以下のコマンドでbuildしてます

$ docker build -t build:self .

ENTRYPOINTもなく、CMDもないDockerfile

Dockerfileは以下、ubuntuのイメージを持ってきただけ

FROM ubuntu:16.04

引数に何も指定しない場合

RUN (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows) - Docker Documentation

とあるので、何もしないとデフォルトである /bin/sh -c が指定されるためシェルが立ち上がる。

$ docker run --rm -it build:self
root@5fcc36125111:/#

引数に何かコマンドを指定した場合

ls を指定すると愚直にlsが行われる

$ docker run --rm -it build:self ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

ENTRYPOINTはないが、CMDがある場合

Dockerfileは以下、CMDとして ls -a にした

FROM ubuntu:16.04

CMD ["ls","-a"]

引数に何も指定しない場合

わかりやすくコマンド実行

$ docker run --rm -it build:self
.   .dockerenv  boot  etc   lib    media  opt   root  sbin  sys  usr
..  bin         dev   home  lib64  mnt    proc  run   srv   tmp  var

引数に何かコマンドを指定した場合

上書きで実行

$ docker run --rm -it build:self pwd
/

引数にオプションで指定した場合

エラー

$ docker run --rm -it build:self -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.

ENTRYPOINTはあるが、CMDがない場合

Dockerfileは以下、ENTRYPOINTとして ls -a にした

FROM ubuntu:16.04

ENTRYPOINT ["ls","-a"]

引数に何も指定しない場合

問題なくコマンド実行

$ docker run --rm -it build:self
.   .dockerenv  boot  etc   lib    media  opt   root  sbin  sys  usr
..  bin         dev   home  lib64  mnt    proc  run   srv   tmp  var

引数に何かコマンドを指定した場合

エラー、おそらく ls pwd で実行された

$ docker run --rm -it build:self pwd
ls: cannot access 'pwd': No such file or directory

引数にオプションで指定した場合

オプションが認識されて実行される

a$ docker run --rm -it build:self -l
total 72
drwxr-xr-x   1 root root 4096 Jan 27 08:40 .
drwxr-xr-x   1 root root 4096 Jan 27 08:40 ..
-rwxr-xr-x   1 root root    0 Jan 27 08:40 .dockerenv
drwxr-xr-x   2 root root 4096 Jan 22 19:22 bin
drwxr-xr-x   2 root root 4096 Apr 12  2016 boot
drwxr-xr-x   5 root root  360 Jan 27 08:40 dev
drwxr-xr-x   1 root root 4096 Jan 27 08:40 etc
drwxr-xr-x   2 root root 4096 Apr 12  2016 home
drwxr-xr-x   8 root root 4096 Sep 13  2015 lib
drwxr-xr-x   2 root root 4096 Jan 22 19:22 lib64
drwxr-xr-x   2 root root 4096 Jan 22 19:22 media
drwxr-xr-x   2 root root 4096 Jan 22 19:22 mnt
drwxr-xr-x   2 root root 4096 Jan 22 19:22 opt
dr-xr-xr-x 170 root root    0 Jan 27 08:40 proc
drwx------   2 root root 4096 Jan 22 19:22 root
drwxr-xr-x   1 root root 4096 Jan 22 19:22 run
drwxr-xr-x   1 root root 4096 Jan 22 22:48 sbin
drwxr-xr-x   2 root root 4096 Jan 22 19:22 srv
dr-xr-xr-x  13 root root    0 Jan 27 08:20 sys
drwxrwxrwt   2 root root 4096 Jan 22 19:22 tmp
drwxr-xr-x   1 root root 4096 Jan 22 19:22 usr
drwxr-xr-x   1 root root 4096 Jan 22 19:22 var

ENTRYPOINTもCMDもある場合

Dockerfileは以下、CMDも入れる。

FROM ubuntu:16.04

ENTRYPOINT ["ls","-a"]
CMD ["-l"]

引数に何も指定しない場合

問題なく合わさった形でコマンド実行

$ docker run --rm -it build:self
total 72
drwxr-xr-x   1 root root 4096 Jan 27 08:44 .
drwxr-xr-x   1 root root 4096 Jan 27 08:44 ..
-rwxr-xr-x   1 root root    0 Jan 27 08:44 .dockerenv
drwxr-xr-x   2 root root 4096 Jan 22 19:22 bin
drwxr-xr-x   2 root root 4096 Apr 12  2016 boot
drwxr-xr-x   5 root root  360 Jan 27 08:44 dev
drwxr-xr-x   1 root root 4096 Jan 27 08:44 etc
drwxr-xr-x   2 root root 4096 Apr 12  2016 home
drwxr-xr-x   8 root root 4096 Sep 13  2015 lib
drwxr-xr-x   2 root root 4096 Jan 22 19:22 lib64
drwxr-xr-x   2 root root 4096 Jan 22 19:22 media
drwxr-xr-x   2 root root 4096 Jan 22 19:22 mnt
drwxr-xr-x   2 root root 4096 Jan 22 19:22 opt
dr-xr-xr-x 170 root root    0 Jan 27 08:44 proc
drwx------   2 root root 4096 Jan 22 19:22 root
drwxr-xr-x   1 root root 4096 Jan 22 19:22 run
drwxr-xr-x   1 root root 4096 Jan 22 22:48 sbin
drwxr-xr-x   2 root root 4096 Jan 22 19:22 srv
dr-xr-xr-x  13 root root    0 Jan 27 08:20 sys
drwxrwxrwt   2 root root 4096 Jan 22 19:22 tmp
drwxr-xr-x   1 root root 4096 Jan 22 19:22 usr
drwxr-xr-x   1 root root 4096 Jan 22 19:22 var

引数に何かコマンドを指定した場合

エラー、おそらく ls pwd で実行された

$ docker run --rm -it build:self pwd
ls: cannot access 'pwd': No such file or directory

引数にオプションで指定した場合

CMDで指定したオプションが上書きされる

$ docker run --rm -it build:self -r
var  tmp  srv   run   proc  mnt    lib64  home  dev   bin         ..
usr  sys  sbin  root  opt   media  lib    etc   boot  .dockerenv  .

参考リンク