## 🐳 [[Docker]]イメージダイエットの始まり:`docker history`でルーツを徹底分析 {#sec-168deae1dd0f} 軽いアプリケーションをデプロイしただけなのに、イメージサイズを確認すると、いつの間にか1GBを超えていることがあります。「あれ、こんなに何も入れてないはずなのに?」と戸惑ってしまうでしょう。そんな時に必要となるのが、イメージの「家系図」を調べる作業です。 ![Dockerレイヤーダイエット](/media/whitedec/blog_img/de42f6f1949c4e91bc6defa030f10ea5.webp) ## 「一体何を食べてそんなに大きくなったの?」 {#sec-5eaafdc2833e} Dockerイメージは、何層にも重なった玉ねぎの皮(レイヤー)のようなものです。`docker history`は、この皮を一枚ずつ剥がし、肥大化の原因となっている「犯人」を特定するためのX線のようなコマンドです。 基本的な使い方は非常にシンプルです。 ```bash # 基本的な使い方 docker history [オプション] <イメージ名:タグ> # 例:自分のアプリの履歴を確認 docker history my-app:latest ``` コマンドを実行すると、イメージの最新レイヤーからベースイメージまで、逆順に表示されます。 ```text IMAGE CREATED CREATED BY SIZE a6215f271958 5 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B 7 weeks ago /bin/sh -c #(nop) ADD file:f28242cf608f6... 7.81MB ``` ここで**SIZE**項目に注目してください。0Bであるべき場所に数百MBと表示されている場合、それがダイエットの対象です。経験を積むと、「何かおかしい」と感じる場所が必ず見つかるはずです。 > \*\*💡 役立つヒント: `--no-trunc** ` > > デフォルトの出力では、コマンドが長いと途中で省略されます。この時`--no-trunc`オプションを付けると、省略されずにコマンド全体を確認できるため、正確な分析には不可欠です。 > > `docker history --no-trunc my-app:latest` *** ## 実例:「犯人は`chown`だった」 {#sec-036665971432} 実際に私が経験した実話をお話ししましょう。150MBのプロジェクトファイルをビルドしたところ、イメージが300MBを超えてしまうという奇妙な現象がありました。犯人は、ごく普通のDockerfileのたった2行だったのです。 **[非効率な方法:2つのレイヤーが生成される]** ```dockerfile # 1. ファイルを一時的にコピー (デフォルトではroot権限でコピーされる) COPY . . # 2. セキュリティのために所有権を変更 (別のコマンドとして実行) RUN chown -R appuser:appgroup /app ``` これをビルドした後、`docker history`で確認してみると、このような結果が表示されました。 ```text IMAGE CREATED BY SIZE /bin/sh -c chown -R appuser:appgroup /app 150MB <-- (問題の箇所!) /bin/sh -c #(nop) COPY dir:abc in /app 150MB ``` ここでDockerレイヤーの恐ろしい点が明らかになります。ステップ1で150MBのファイルをコピーすると、1つのレイヤーが生成されます。しかし、ステップ2で`chown`を実行すると、Dockerは「おや?ファイル情報(所有権)が変わったな?それなら、変更された状態でさらにレイヤーを一つ作ろう!」と判断し、既存の150MBをそのままコピーして新しいレイヤーを積み重ねてしまうのです。 結果として、内容は同じなのに所有権だけが異なるファイルが二重に保存され、容量が2倍になってしまったのです。 *** ## 解決策は一行ダイエット! {#sec-b564ee91d4d9} 解決策は簡単です。コピーする際に最初から所有権を指定し、レイヤーを一つにまとめれば良いのです。 **[効率的な方法:1つのレイヤーが生成される]** ```dockerfile # コピーと同時に所有権も指定! COPY --chown=appuser:appgroup . . ``` Dockerfileをこのように修正し、再度`docker history`を実行してみると、結果は劇的に変わります。 ```text IMAGE CREATED BY SIZE /bin/sh -c #(nop) COPY --chown=appuser... dir:abc 150MB ``` お分かりでしょうか?たった一つのレイヤーのみが生成され、イメージ容量は再びスリムな150MBに戻りました。コマンドを2行から1行にまとめただけで、容量が半分になったのです。 *** ## 結論:ビルド後は必ず「履歴」をチェック! {#sec-74645a10d229} [[Docker]]イメージは**コマンド1行につき1レイヤー**という事実を忘れないでください。 コードを書き終えてテストを行うように、ビルド後には習慣的に`docker history --no-trunc`を実行してみてください。「この`apt-get`はなぜこんなに重いんだ?」「このレイヤーはなぜわざわざ分けたのだろう?」といった疑問が次々と湧いてくるうちに、いつの間にか非常に軽量で効率的なシステムを構築していることでしょう。 不要なレイヤーはシステムの敵ですからね! *** **お役に立ちましたでしょうか?** もしお役に立てたなら、ぜひ「いいね!」をお願いします。 関連記事もぜひご覧ください。 **関連記事** [Docker共有メモリ(shm_sizeとipc)を完全に理解する](/ko/whitedec/2025/11/5/docker-shm-size-ipc/) [Docker: ネットワーク共有なしでホストポートを介してコンテナ間で通信する](/ko/whitedec/2025/11/4/docker-host-port-container-communication/) [Dockerボリュームのコピー、「なぜ」そうする必要があるのか?](/ko/whitedec/2025/11/10/docker-volume-copy-reason/)