DiveでDockerイメージを覗いてサイズを減らす方法

お疲れ様です。MUGENUP エンジニアの崔です。今回はDiveというツールを使ってDockerイメージの中身を見る方法を紹介しようと思います。

なぜ必要?

イメージを作るときにCentOSDebianのイメージ自体も300から600メガになるし、パッケージを設置したり、重いファイルを入れるとすぐギガバイトまで行くかと思います。 開発環境は多少イメージが多くてもdocker image pruneなどの立ち上がっていないイメージを消すコマンドをたたくことで容量を確保しますが、本番環境や他のイメージのベースのなるイメージだったらなるべくイメージのサイズを軽くする必要があると思います。

Diveとは?

Diveは対話型CLIツールでイメージのIDを入れるとイメージのステップごとにその中身のディレクトリー構造が見れるツールです。

https://github.com/wagoodman/dive

まずツールを実行すると二つの窓に別れています。 左の方はステップをキーボードの上下キーで次、前のステップに移動するのができます。 右の方は今選択したステップのイメージレイヤのディレクトリー構造が見れます。 で、お互いの窓をスペースキーで転換できます。

イメージを分析しよう!

ではツールをインストールしたら(MacとかLinuxのメージャーなDistroならパッケージマネジャーから設置できます!)実際これを使って分析しましょう。

まず、ターゲットになるイメージを選択する為にイメージのリストをみましょう。

$ docker images -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
***_backend      latest              b9d23b76e550        2 hours ago         333MB
***_console      latest              b9d23b76e550        2 hours ago         333MB
<none>              <none>              b56bd1bd77f4        2 hours ago         333MB
<none>              <none>              3a8d411fa803        2 hours ago         333MB
<none>              <none>              3df2afeb812e        2 hours ago         333MB
<none>              <none>              628311edb63b        2 hours ago         51.2MB
<none>              <none>              f6c2a2f82ff8        2 hours ago         51.2MB
***_frontend     latest              5772f1e7234a        2 hours ago         372MB

で、今回はfrontedイメージの中身を見ましょう

$ dive 5772f1e7234a
Image Source: docker://5772f1e7234a
Fetching image... (this can take a while for large images)

diveの初期画面

まず最初に実行した画面です。

diveの画面2 見ての通り二つの窓があります。タブキーで左右移動して上下で要素に接近できます。 左からは一個下に進んで見て、右画面にファイルの変更が色に表示されます。 ここで一旦ステップを踏んでみましょう。

diveの画面3 distが5メガ

ここでは本来ならいないはずのdistフォルダーのトランスファイルされたファイルたちがイメージに入ってしましましたね。 ここが一旦消すところですね。

diveの画面4 node_modulesが154メガ

ここでもう一個発見しました。node_modulesです。次のステップでどうせnpm installが走るからnode_modulesが生成されるから除外しなくても良いと思うかも知れませんが、、、 node_modulesには開発環境で一回インストールして要らなくなったパッケージとかあるかも知れないので自分は削除する判断をしました。

削除

削除とは言いましたが、ただイメージに先発見したファイルが入れなくなる過程ですね。 Dockerイメージに入れたくないファイルがあったら.dockerignoreで記載できます。 自分の場合は.dockerignoreファイルにnode_modulesdistとを入れます

$ cat .dockerignore
node_modules
dist

後、npm install --only=prodみたいにdevDependencies(開発環境だけ必要なパッケージ、npm install --save-devでインストールしたもの)は場外するようにDockerfileも変えれば良さそうですね。

今回の例はそこまで大きいプロジェクトではなかったので多い変化はないけど、イメージが重い!毎回新しいイメージの生成でディスク足りない!!って方はどこか無駄にコピーしているファイルはないか、確認のときにはぜひ使ってみてください。


DiveのCLI画面ではCtrl+Cで終了、Ctrl+Fでファイル名から探すなど必要な機能としては足りないかと思います しかもDiveは効率度(efficiency)を測定したり、CIモード設定でイメージのサイズが一定以上とか、効率度が低くなるとPass/Failをリターンコードとして返してくれるらしいので色々使えるツールかと思います。

これでDockerイメージの内部を見れる良いツールdiveで楽しいDocker開発になったら嬉しいです。最後まで読んでくれてありがとうございます!