0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker】 `CMD`と`ENTRYPOINT`の違いについて理解した

Posted at

h

現在、本業でPythonをdockerで動かしています。
その中で、コンテナ起動時にpythonを実行する仕様にしている中でCMDENTRYPOINTの違いについて調べたのでまとめました。

基本概念

docker runでコンテナを起動するときに使用します。

指令 役割 上書き方法
CMD デフォルトの引数定義 docker runの引数で直接変更
ENTRYPOINT コンテナのメインプロセス定義 --entrypointフラグが必要

1つのDockerfile内でCMD,ENTRYPOINTをそれぞれ一度しか使用できないことに注意してください。
※複数記載した場合、最後に定義したものが実行されます。

CMDENTRYPOINTは何が違うか

結論、CMDは柔軟な設定が可能で、ENTRYPOINTは必ず実行させたいコマンドが設定可能です。
故に、それぞれ単体で使用するケースと、二つを柔軟に組み合わせて使用するケースがあります。
以下にチートシートを作成したので、参考にしてみてください。

各コマンドの使い分け

ケース 推奨 理由
デフォルトの引数だけ指定したい(簡単に上書きさせたい) CMD 単体 実行時の引数で簡単に変更可能
実行させたいコマンドを固定したい(常に実行させる) ENTRYPOINT 単体 ユーザーが指定した引数が付け加えられるだけ
実行コマンドを固定しつつ、引数はデフォルトを与えつつ変更も許したい ENTRYPOINT + CMD 実行ファイル+その引数として動作する

上書きの挙動

使い方 docker run時の上書き可否 説明
CMDのみ docker run イメージ名 新しい引数 で上書き可能 柔軟に変えたい時に便利
ENTRYPOINTのみ docker runの引数はすべてENTRYPOINTの引数になる コマンドは変わらない
ENTRYPOINT + CMD CMD部分だけ上書き可能 コマンドは固定・引数だけ変えられる
ENTRYPOINTを変更したい場合 --entrypoint を明示的に指定 CMDだけでは変更不可

使い所

シーン 使い方 理由
デバッグや試行錯誤 CMDのみ 柔軟性が高い。runの都度挙動を変えやすい
スクリプト実行ツールとして配布 ENTRYPOINTのみ 実行内容を強制できる(例:CLIツール)
初期化スクリプト+引数指定 ENTRYPOINT + CMD ENTRYPOINTでスクリプト、CMDで引数をデフォルト指定

ハンズオン環境

実際に再現してみました。
簡単なので、眺めるだけでもある程度理解できると思います。
もし、ハンズオン的に触ってみたい方は GitHub にソースがあります。
https://github.com/shunyonai1996/docker-cmd-entrypoint-demo

$ tree
.
├── article.md
├── Dockerfile-both
├── Dockerfile-cmd
└── Dockerfile-entrypoint

CMD

一応概要から。。。
CMDはコンテナを実行したときの「デフォルトのコマンドや引数」を指定するものです。
特徴として、docker run実行時、引数を上書きできます。

CMD の主な目的は、コンテナ実行時のデフォルト(初期設定)を指定するためです 。
https://docs.docker.jp/engine/reference/builder.html#cmd

Dockerfile-cmd

FROM alpine:latest
CMD ["echo", "Hello CMD"]
# build
$ docker build -t cmd-demo -f Dockerfile-cmd .
[+] Building 2.0s (5/5) FINISHED

# run
$ docker run cmd-demo
Hello CMD

# 実行時、コマンドを上書き
$ docker run cmd-demo echo "Overridden CMD"
Overridden CMD

ENTRYPOINT

こちらも概要から。
ENTRYPOINTはコンテナを「実行ファイル」として動かすため、常に実行されるコマンドを指定します。
docker runの引数はENTRYPOINTへの引数として追加される。
ENTRYPOINT自体を変えたい場合は--entrypointオプションが必要。

ちなみに「コンテナを実行ファイルとして動かす」という表現が当初よくわからなかったので、補足します(飛ばしてもいいです)。
難しく考えなくて良くて、DockerfileENTRYPOINT["echo"]と記載し、docker run Helloを実行したとしましょう。

docker run my-image Hello World
# => Hello World

上記は以下と全く同じ意味合いです。

echo Hello World

つまり、docker run コンテナ名 引数という形で、あたかもコマンドに引数を渡すようなインターフェースに見えるということを指しています。

ENTRYPOINT は、コンテナを 実行ファイルexecutable として処理するように設定できます。

Dockerfile-entrypoint

FROM alpine:latest
ENTRYPOINT ["echo", "Hello ENTRYPOINT"]
# build
$ docker build -t entrypoint-demo -f Dockerfile-entrypoint .
[+] Building 2.1s (5/5) FINISHED

# run
$ docker run entrypoint-demo
Hello ENTRYPOINT

# 実行時、コマンドを上書き
$ docker run --entrypoint="" entrypoint-demo echo "Overridden ENTRYPOINT"
Overridden ENTRYPOINT

CMD & ENTRYPOINT

ENTRYPOINTが「実行するコマンド」、CMDが「そのコマンドのデフォルト引数」になる。

Dockerfile-both

FROM alpine:latest
ENTRYPOINT ["echo"]
CMD ["Hello ENTRYPOINT & CMD"]
# build
$ docker build -t both-demo -f Dockerfile-both .
[+] Building 0.9s (5/5) FINISHED

# run
$ docker run both-demo
Hello ENTRYPOINT & CMD

# 実行時、引数を変更
$ docker run both-demo "Custom Argument"
Custom Argument
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?