【ツール活用|実務向け】Dockerfile設計の要:ENTRYPOINTとCMDを使いこなして「柔軟なコンテナ」を作る方法

1. 導入:なぜENTRYPOINTとCMDの理解が重要なのか

コンテナを構築する際、多くの方が直面するのが「どのコマンドをどこに書くべきか」という悩みです。ENTRYPOINTとCMDを適切に使い分けることで、コンテナを「固定的なサービス」としてだけでなく、「柔軟なコマンドラインツール」として運用できるようになります。本記事では、両者の優先順位と、実務で役立つ「引数上書き」のベストプラクティスを解説します。

2. 基礎知識:ENTRYPOINTとCMDの役割

Dockerfileにおける実行制御には主に2つの命令があります。

ENTRYPOINT: コンテナが起動した際に必ず実行される「メインの実行ファイル」を指定します。上書きされにくく、コンテナの役割を固定するために使用します。
CMD: ENTRYPOINTに渡される「デフォルト引数」を指定します。コンテナ実行時にユーザーが引数を渡すと、この値は簡単に上書きされます。

この2つを組み合わせることで、「固定のプログラム(ENTRYPOINT)」に対して「柔軟なパラメータ(CMD)」を与えるという、非常に効率的な設計が可能になります。

3. 実装と解決策:優先順位の理解

Dockerは「ENTRYPOINT」を優先し、「CMD」を補足的に扱います。もしDockerfile内で両方を定義すると、CMDの内容はENTRYPOINTの引数として渡されます。

重要なのは、docker runコマンドで引数を指定した場合、Dockerfile内のCMDは無視され、ユーザーが入力した値がENTRYPOINTの引数として渡されるという点です。これにより、イメージをビルドし直すことなく、実行時のみコマンドの挙動を変更することが可能になります。

4. サンプルプログラム:コマンドラインツール風コンテナ

以下のDockerfileは、Pythonスクリプトをコンテナ化し、デフォルト引数を持ちつつ、実行時に動的に引数を変更できる構成例です。

Dockerfileの例
FROM python:3.9-slim

作業ディレクトリの設定
WORKDIR /app

実行用スクリプトを配置(例:greet.py)
処理内容: 引数で渡された名前に対して挨拶をする
RUN echo ‘import sys; print(f”Hello, {sys.argv[1]}!”)’ > greet.py

ENTRYPOINTで実行バイナリを固定
ENTRYPOINT [“python”, “greet.py”]

CMDでデフォルトの引数を指定(実行時に上書き可能)
CMD [“World”]

— 実行確認 —
1. デフォルト実行: “Hello, World!” と表示される
docker run <イメージ名>

2. 引数上書き実行: “Hello, DevOps!” と表示される
docker run <イメージ名> DevOps

5. 応用・注意点:現場で陥りやすい罠

実務で設計する際は、以下の点に注意してください。

シェル形式とexec形式の違い: 上記サンプルで使用している [“executable”, “param”] という「exec形式」を推奨します。シェル形式(ENTRYPOINT python greet.py)で記述すると、PID 1としてシェルが起動してしまい、シグナル(SIGTERMなど)が正しく子プロセスに伝わらず、コンテナの正常終了ができなくなるリスクがあります。

上書きの意図的禁止: もしユーザーに引数を変更されたくない場合は、CMDを使わずENTRYPOINTのみでコマンドを完結させてください。逆に、コンテナの挙動を完全にユーザー側に委ねる場合は、ENTRYPOINTをシェルスクリプトにし、その中で引数の有無を判定するロジックを組むのがプロフェッショナルな設計です。

この仕組みを理解すれば、CI/CDパイプライン上で環境ごとに引数を変えて実行するような、堅牢なコンテナ基盤を構築できるはずです。

コメント

タイトルとURLをコピーしました