diveコマンドでDockerイメージのレイヤーを分析する方法|不要ファイルの検出とDockerfile最適化の実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Docker > diveコマンドでDockerイメージのレイヤーを分析する方法|不要ファイルの検出とDockerfile最適化の実践手順
「docker buildで作ったイメージのサイズが思ったより大きい」「セキュリティスキャンで中間レイヤーに秘密情報が残っているという警告が出た」

Dockerfileを設計していると、RUN命令の書き方次第でキャッシュや一時ファイルが最終イメージに混入し、予期せずサイズが膨らむことがあります。docker image inspectではレイヤー構造の詳細は見えないため、どこが問題なのか特定が難しい。

この記事では、Dockerイメージのレイヤーを対話型UIで可視化できるdiveコマンドの使い方を解説します。Rocky Linux 9.4 + Docker 26.1.4の実機で動作確認した、インストールから基本操作・問題パターンの発見・Dockerfile改善・CI組み込みまでをひとつの流れで紹介します。

この記事のポイント

・diveコマンドはDockerイメージのレイヤーをファイル単位で可視化するツール
・対話型UIで各レイヤーのファイル追加・削除・変更を確認できる
・効率スコアで「無駄なスペース」を数値化しDockerfile改善の優先度を把握できる
・--ciフラグでCIパイプラインへの組み込みが可能


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

diveとは何か

dive(ダイブ)は、DockerイメージのレイヤーをインタラクティブなターミナルUIで分析できるオープンソースのツールです。

docker image historyコマンドでもレイヤーごとのサイズは確認できますが、「どのファイルが追加・変更・削除されたか」まではわかりません。diveはレイヤーを選択するとそのレイヤーで変更されたファイルツリーを表示するため、問題の所在を正確に把握できます。

可視化対象:イメージの各レイヤーとその差分ファイル
主な用途:イメージサイズの肥大化原因の調査、中間レイヤーの不要ファイル特定
出力形式:対話型UI(ターミナル)またはCI向けのレポート出力
GitHub:wagoodman/dive(v0.12.0以降、Rocky Linux 9 / Ubuntu 24対応)

diveのインストール方法

1. Rocky Linux / RHEL系へのインストール

GitHub Releasesからrpmパッケージを取得してインストールします。

# diveのバージョンを変数に設定 DIVE_VERSION=0.12.0 # rpmパッケージをダウンロード curl -L -o /tmp/dive.rpm \ https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.rpm # インストール sudo rpm -ivh /tmp/dive.rpm # バージョン確認 dive --version

インストール完了後のバージョン確認出力は以下のようになります。

dive 0.12.0

2. Ubuntu / Debian系へのインストール

DIVE_VERSION=0.12.0 curl -L -o /tmp/dive.deb \ https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.deb sudo dpkg -i /tmp/dive.deb dive --version

3. Dockerコンテナとして実行する

インストール不要で試したい場合は、コンテナとして実行できます。Dockerソケットのマウントが必要です。

docker run --rm -it \ -v /var/run/docker.sock:/var/run/docker.sock \ wagoodman/dive:latest nginx:1.27-alpine

diveの基本的な使い方

1. 対話型UIを起動する

分析したいイメージ名またはIDを引数に渡して実行します。

# ローカルイメージを分析 dive nginx:1.27-alpine # ビルドと同時に分析 dive build -t myapp:latest .

起動直後のターミナル出力は以下のようになります。

Image Source: docker://nginx:1.27-alpine Fetching image... (this can take a while for large images) Analyzing image... Building cache...

2. 画面の見方

diveのUIは左右2ペイン構成です。

左ペイン(Layers):FROM命令を起点にした各レイヤーの一覧。サイズとDockerfileの命令が表示される
右ペイン(Current Layer Changes):選択中のレイヤーで変更されたファイルツリー。A(追加)・R(削除)・C(変更)のマーカー付き
下部(Image Details):Total Image Size / Potential wasted space / Image efficiency scoreの3指標

主なキーバインドは以下のとおりです。
キー 操作
Tab 左右ペイン間の切り替え
↑ / ↓ レイヤー・ファイルの移動
Space ファイルツリーの展開/折りたたみ
Ctrl+F ファイル名検索
Ctrl+A 変更ファイルのみ表示切り替え
Ctrl+Z 変更種別(A/R/C)でフィルタ
Ctrl+C 終了

3. 効率スコアの読み方

画面下部に表示される3つの指標が、イメージ改善の判断基準になります。

Total Image size:イメージ全体の圧縮前サイズ
Potential wasted space:中間レイヤーで削除されたファイルなど、無駄に占有しているバイト数
Image efficiency score:100%が理論上の最大効率。90%を下回るイメージは改善余地が大きい
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Dockerハンズオン研修の詳細を見る >>

diveでよく見つかる問題パターン

1. パッケージマネージャのキャッシュが残っている

最もよく見られる問題です。yum installapt-get installを単独のRUN命令で書くと、キャッシュファイルが別レイヤーに保存されます。次のRUN命令でキャッシュを削除しても、Dockerのレイヤー設計上、削除前のレイヤーはイメージに残り続けます。

diveでこのパターンを発見した場合、左ペインでパッケージインストール命令のレイヤーを選択し、右ペインで/var/cache/yum/var/lib/apt/lists配下にファイルが残っていないか確認します。

# 問題のあるDockerfile(キャッシュが別レイヤーに残る) RUN yum install -y curl RUN yum clean all # diveのImage Details欄(改善前) Potential wasted space: 42 MB Image efficiency score: 78 %

2. 中間レイヤーに秘密情報が残っている

ビルド時にトークンやAPIキーをRUN命令で渡した場合、そのレイヤーはイメージにそのまま記録されます。後のレイヤーで削除しても、docker history --no-truncやdiveでは復元可能な状態で残ります。

diveの右ペインでCtrl+Fを使い、.envや秘密鍵ファイル等が中間レイヤーに存在しないか確認します。発見した場合はRUN --mount=type=secretかマルチステージビルドへの移行が必要です。

3. ビルドツールが最終イメージに含まれている

gccmakepip等のビルドツールは、コンパイルやパッケージインストールに使うだけで本番稼働には不要です。これらが最終イメージに含まれると、サイズが増加するだけでなく攻撃面も広がります。

diveで/usr/bin/gcc等のパスを右ペインで確認し、本番用の最終レイヤーに存在する場合はマルチステージビルドへの移行を検討します。

diveの発見をDockerfileに反映する

1. RUN命令をチェーンして一時ファイルを同一レイヤーで削除する

パッケージインストールとキャッシュ削除を1つのRUN命令にまとめると、中間ファイルが別レイヤーに残りません。

# 改善後のDockerfile(RUNをチェーンして同一レイヤーで削除) RUN yum install -y curl \ && yum clean all \ && rm -rf /var/cache/yum # diveのImage Details欄(改善後) Potential wasted space: 0 bytes Image efficiency score: 100 %

2. マルチステージビルドで解決する

ビルドツールが最終イメージに含まれる問題は、マルチステージビルドで根本解決できます。ビルドステージと実行ステージを分離し、実行ステージには成果物だけをコピーします。

# ビルドステージ(ビルドツールを使い捨て) FROM golang:1.22-alpine AS builder WORKDIR /src COPY . . RUN go build -o /app ./cmd/server # 実行ステージ(バイナリだけをコピー) FROM alpine:3.20 COPY --from=builder /app /app CMD ["/app"]

このパターンでdiveを実行すると、最終イメージにGoのビルドツールが一切含まれず、効率スコアが大幅に改善されます。diveで確認した出力例は次のとおりです。

# マルチステージ適用後のImage Details Total Image size: 8.1 MB ← ビルドステージ含む場合は380 MB Potential wasted space: 0 bytes Image efficiency score: 100 %

CIでdiveを自動実行する

--ciフラグを付けると、対話型UIを表示せず効率スコアの判定結果のみを出力し、閾値を超えた場合に終了コード1を返します。CIパイプラインでのゲートとして組み込むと、Dockerfileの品質劣化を自動検出できます。

# CIモードで実行 dive --ci myapp:latest

実際の出力例は以下のとおりです。

efficiency: 98.4521 % wastedBytes: 142355 bytes (142 kB) userWastedPercent: 0.0000 % Result:PASS [Total:3] [Passed:3] [Failed:0] [Warn:0] [Skipped:0]

閾値はプロジェクトルートの.dive-ciファイルで設定できます。

# .dive-ci(YAMLフォーマット) rules: # 効率スコアが95%を下回った場合にNG lowestEfficiency: 0.95 # 中間レイヤーで削除されたファイルが10MB以上ならNG highestWastedBytes: 10000000 # ユーザーが引き起こした無駄が1%以上ならNG highestUserWastedPercent: 0.01

GitHub Actionsへの組み込み例は以下のとおりです。

# .github/workflows/docker-lint.yml(抜粋) - name: Analyze image with dive run: | docker build -t myapp:ci . dive --ci myapp:ci

トラブルシュート

「cannot connect to the Docker daemon」が出る
Dockerソケットへのアクセス権がないか、dockerdが停止しています。systemctl status dockerでdockerの起動状態を確認し、実行ユーザーがdockerグループに所属しているか確認してください。

分析が途中で止まる(巨大イメージ)
1GB以上のイメージはキャッシュ構築に時間がかかります。dive --source docker-archive myapp.tarでtarファイルを直接読み込むと安定する場合があります。

--ciモードで常にFAILになる
.dive-ciの閾値が厳しすぎる可能性があります。まず--ciなしで対話型UIを起動し、実際のスコアを確認してから閾値を調整してください。

本記事のまとめ

やりたいこと コマンド
ローカルイメージを対話型UIで分析 dive イメージ名:タグ
ビルドと同時に分析 dive build -t イメージ名:タグ .
コンテナで実行(インストール不要) docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest イメージ名
CIモードで効率スコアを判定 dive --ci イメージ名:タグ
変更ファイルのみ右ペインに絞り込む 対話型UI内でCtrl+A
ファイル名で検索 対話型UI内でCtrl+F
diveで問題を発見したら、「RUN命令チェーン化 + 即時削除」か「マルチステージビルドへの移行」の2パターンで対処します。どちらも対応したら再度diveを実行して効率スコアの改善を数値で確認するサイクルを回すと、イメージの肥大化を継続的に防げます。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Dockerハンズオン研修の詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。