Dockerfile とは何か? image を build するためのレシピ
Dockerfile は、image をどう組み立てるかを Docker にステップごとに伝える、プレーンテキストの命令リストです。
image がテンプレートだとすれば、Dockerfile はそれを生み出すレシピです。各命令は順番に実行され、ファイルシステムを変更するとレイヤーを追加します。よく使う命令がどう振る舞うかを知っていることが、10 秒でキャッシュされる build と 10 分かかる build との違いになります。
最もよく使う命令
- FROM - build のベースとなる image。
- RUN - build 時にコマンドを実行する(インストール、コンパイル)。
- COPY / ADD - build context からファイルを image に取り込む。
- WORKDIR, ENV - 作業ディレクトリと環境を設定する。
- CMD / ENTRYPOINT - コンテナ起動時に実行されるもの。
最小限の例
小さな Node アプリは次のようになるかもしれません。
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "server.js"]
この順序は意図的なものです - 以下の cache を参照してください。
cache には順序が重要
Docker は各レイヤーを cache し、命令とその入力が変わらなければそれを再利用します。package*.json をコピーして依存関係をインストールしてから残りのソースをコピーすることで、依存関係が変わったときだけ再インストールされます - コードを編集するたびにではありません。
CMD vs ENTRYPOINT
ENTRYPOINT は常に実行される実行ファイルを設定し、CMD は呼び出し側が上書きできるデフォルト引数を設定します。多くの image は、バイナリに ENTRYPOINT を、そのデフォルトフラグに CMD を使います。
CI で Dockerfile から build する
pipeline は通常、Dockerfile に対して docker build を実行し、その結果を push します。build 時間は cache hit と依存関係のインストールに左右されるため、温まった cache を持つ runner が有利です。マネージド runner(Latchkey)は job 間でレイヤー cache を保持し、これらの build を高速に保ちます。
重要なポイント
- Dockerfile は順序付けられたレシピであり、ファイルシステムを変更する各命令がレイヤーになります。
- cache hit を最大化するために、ソースの前に依存関係をコピーしてインストールします。
- ENTRYPOINT は実行ファイルを設定し、CMD は上書き可能なデフォルト引数を設定します。