概要
Dockerイメージをビルドしていると、意図せず容量が大きくなることがよくあります。そのほとんどの原因は 不必要に生成されたレイヤー にあります。この記事では docker history コマンドを使用してイメージの'系譜'を確認し、これを通じて実際のイメージを軽量化した最適化の経験を共有します。
このコマンドを活用すれば、何がイメージを重くしているのか正確に見つけ出し、より効率的なイメージを作成できます。
docker history: イメージの系譜を確認する
docker historyは特定のイメージがどのように作成されたのか、その構成履歴を表示するコマンドです。Dockerfileの各コマンドがどの レイヤー(layer) に積み重なっているのか、さらに各レイヤーが生成された時点と容量を確認することができます。
基本的な使い方は非常にシンプルです。
docker history [オプション] <イメージ名:タグ>
例えばローカルの my-app:latest イメージのヒストリーを確認するコマンドは次のようになります。
docker history my-app:latest
出力結果を見ると、イメージの一番上のレイヤー(最新)からベースイメージ(最も古い)まで順番に表示されます。
IMAGE CREATED CREATED BY SIZE
a6215f271958 5 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:f28242cf608f6... 7.81MB
-
CREATED BY: このレイヤーを生成したDockerfileコマンド
-
SIZE: 該当レイヤーが占める容量
役立つヒント: --no-truncでコマンド全体を見る
docker historyの基本出力は、CREATED BY列のコマンドが長すぎると途中で切れてしまいます。この時--no-truncオプションを併用すると、切れずに全コマンドを見ることができ、正確な分析に不可欠です。
docker history --no-trunc my-app:latest
レイヤー分析が重要な理由: 実際の最適化経験
DockerイメージはDockerfileの コマンド1行ごとに1つのレイヤー を生成することが基本原則です。そして各レイヤーは前のレイヤーの上に積み重なる'変更'です。
問題は、不必要にレイヤーを分けるとイメージ容量が急激に増加するということです。
事例: COPY と RUN chownの罠
Dockerfileを書く際、プロジェクトファイルをコンテナにコピー(COPY)した後、該当ファイルの所有権を特定のユーザー(例: appuser)に変更(RUN chown)することがよくあります。
非効率的な方法: 2つのレイヤー
最初はDockerfileを次のように書きました。
# 1. ファイルを一旦コピー(root所有でコピーされる)
COPY . .
# 2. 所有権変更(別のコマンドで実行)
RUN chown -R appuser:appgroup /app
docker historyでビルドされたイメージの履歴を確認したところ、2つのレイヤーが作成されていました。
IMAGE CREATED BY SIZE
<layer_id_2> /bin/sh -c chown -R appuser:appgroup /app 150MB <-- (問題!)
<layer_id_1> /bin/sh -c #(nop) COPY dir:abc in /app 150MB
ここで深刻な問題が発生します。
-
COPY . .コマンドで150MBのファイルが レイヤー1 に追加されました。 -
RUN chownコマンドは レイヤー1の150MBファイルをそのままコピー し、所有権情報だけを変更して レイヤー2 に新しく保存します。
ファイル内容は同じですが、一方は root 所有、もう一方は appuser 所有として、それぞれ異なるレイヤーに保存されることになり、結果的にこの2つのレイヤーだけでイメージ総容量は300MB(150MB + 150MB)になります。
効率的な方法: 1つのレイヤー
この問題は COPY コマンドの --chown フラグを使うことで簡単に解決できます。
# 1. コピーと同時に所有権指定
COPY --chown=appuser:appgroup . .
Dockerfileをこのように修正した後、docker historyで再度確認しました。
IMAGE CREATED BY SIZE
<layer_id_1> /bin/sh -c #(nop) COPY --chown=appuser... dir:abc 150MB
1つのレイヤーが生成され、イメージの総容量は150MBに減少しました。たった2行のコマンドを1行にまとめただけで、イメージ容量が半分近く減ったのです。
結論
docker historyは単にイメージの生成履歴を見るだけでなく、 イメージ最適化のための重要な分析ツール です。
Dockerfileを修正した後は、習慣的に docker history --no-trunc を実行して、意図に沿ったレイヤーが生成されたか、不必要に容量を占めるレイヤーがないか確認することが重要です。この小さな習慣が積み重なり、軽量で効率的なイメージを作成できます。
コメントはありません。