DockerfileでENTRYPOINT、CMDを指定した時のベースイメージの挙動はどう変わるか
はじめに
先日投稿した以下のエントリは、今回のエントリを投稿するための前提知識になっています。
前提知識を整理しておきたかったためにまとめたものになっています。
僕らが Dockerfile
を記述するときには、一行目に FROM というコマンドを記述します。
これは、Dockerイメージを作成する際に利用する ベースイメージ を指定するための命令となります。
ベースイメージも Dockerfile からビルドされたDockerイメージであり、 ENTRYPOINT や CMD コマンドが Dcokerfile 内に記述されている場合があるわけです。
自分で作成するDockerfileに ENTRYPOINT や CMD コマンドを記述した場合、それらはベースイメージの ENTRYOPTION や CMD とどう連携して動作するのでしょうか?
実験してみたいと思います。
検証環境
$ uname -moi
x86_64 MacBookPro16,1 Darwin
$ docker --version
Docker version 19.03.13, build 4484c46d9d
実験の流れ
- ENTRYPOINT / CMD コマンドをそれぞれ設定した Dockerfile を作成・ビルドし、作成されたDockerイメージを実行してみる
- (1)で作成したDockerイメージを「ベースイメージ」とした Dockerfile を作成・ビルドし、作成されたDockerイメージを実行してみる。作成するDockerfileは以下の4つのパターンとする
- ENTRYPOINT、CMD の両方を設定しない
- ENTRYPOINT、CMD の両方を設定する
- ENTRYPOINT だけ設定する
- CMD だけ設定する
親となるDockerfileの作成・ビルド・実行
まずは 親 となるDockerfileを作成します。
# cat <<EOF >Dockerfile
FROM bash
ENTRYPOINT ["echo"]
CMD ["2", "5"]
EOF
ビルドします。( イメージ名は parent という名前で作成します。 )
$ docker build -t parent .
実行します。
$ docker run parent
2 5
ENTRYPOINT と CMD の挙動の仕組みがまだ把握できていない場合は、以下のエントリを読んで頂くことをおすすめします。
子となるDockerfileの作成・ビルド・実行
先程作成したばかりのベースイメージとなるDockerイメージを使って、新たなDockerイメージを作り、実行させてみます。
新たなDockerfileは4つのパターンのものを作成してみます。
1. ENTRYPOINT、CMD の両方を設定しない
Dockerfileを作成・ビルド・実行します。
※ベースイメージには先程作成したDockerイメージを利用します。 (イメージ名は parent でしたね。)
# 作成
$ cat <<EOF >Dockerfile
FROM parent
EOF
# ビルド
$ docker build -t child1 .
# 実行
$ docker run child1
2 5
ENTRYPOINT、CMD の両方を設定しない場合は、ベースイメージの設定がそのまま利用されます。
2. ENTRYPOINT、CMD の両方を設定する
Dockerfileを作成・ビルド・実行します。
※ベースイメージには先程作成したDockerイメージを利用します。
# 作成
$ cat <<EOF >Dockerfile
FROM parent
ENTRYPOINT ["seq"]
CMD ["3", "4"]
EOF
# ビルド
$ docker build -t child2 .
# 実行
$ docker run child2
3
4
ENTRYPOINT、CMDを設定する場合は、ベースイメージの設定が上書きされます。
3. ENTRYPOINT だけ設定する
Dockerfileを作成・ビルド・実行します。
※ベースイメージには先程作成したDockerイメージを利用します。
# 作成
$ cat <<EOF >Dockerfile
FROM parent
ENTRYPOINT ["seq"]
EOF
# ビルド
$ docker build -t child3 .
# 実行
$ docker run child3
BusyBox v1.31.1 () multi-call binary.
Usage: seq [-w] [-s SEP] [FIRST [INC]] LAST
Print numbers from FIRST to LAST, in steps of INC.
FIRST, INC default to 1.
-w Pad to last with leading zeros
-s SEP String separator
少々分かりにくいですが、これは seq
コマンドを引数無しで実行した結果となっています。
ENTRYPOINT だけを設定する場合は、ベースイメージの設定が上書きされると同時に、 CMD 設定がクリアされ、 ENTRYPOINT だけが設定されている状態となります。
4. CMD だけ設定する
Dockerfileを作成・ビルド・実行します。
※ベースイメージには先程作成したDockerイメージを利用します。
# 作成
$ cat <<EOF >Dockerfile
FROM parent
CMD ["7", "10"]
EOF
# ビルド
$ docker build -t child4 .
# 実行
$ docker run child4
7 10
CMD だけを設定する場合は、ベースイメージの CMD 設定が上書きされますが、 ENTRYPOINT の設定はそのまま引き継がれます。
ひとこと
この挙動をどう有効活用するのがベストプラクティスなのかは深く理解できておらず。
ディスカッション
コメント一覧
まだ、コメントがありません