LLMを活用してDockerfileを最適化し15%のサイズ削減を実現した話
3行まとめ
- LLM を活用して Dockerfile のリファクタリングを実施し、イメージサイズを 15%削減(1.96GB → 1.75GB)
- LLM 登場前に書いたコードを LLM にリファクタさせるのは良い結果を生む(最近これが楽しい)
- slim イメージへの移行とパッケージ最適化により、ビルド時間と pull 時間を改善
背景
長年運用している Dockerfile は複雑化していく傾向にあります。
リファクタリングはリグレッションのリスクがあり、手を出しづらいです。
最近、Devin による Dockerfileリファクタリングの成功事例を見て、自プロジェクトでも試してみることにしました。
最適化前の状態
まず、変更前の Docker image のサイズを調べておきます。
❯ docker images minedia-www-appREPOSITORY TAG IMAGE ID CREATED SIZEminedia-www-app latest 7e88a3086cb9 4 days ago 1.96GB2GBありました。
アプローチ
Devinにやってもらおうかと思いましたが、そもそもこんなDockerfileのリファクタだったらClineで十分だと思うのでClineでClaude sonnet 3.5(少し前に行ったので古い)で実行してみました。
プロンプトは、ラフに「Dockerfileをリファクタリングして」という指示だけです。
LLMによる主要な変更点
1. ベースイメージの最適化
FROM ruby:3.4.1FROM ruby:3.4.1-slim必要最低限しか入っていない -slim をbase imageとして使うようになりました。
いままでも導入を検討していましたが、開発時にはツールが少なかったり、リグレッションが発生してしまうリスクがあるのであんまり導入に積極的に離れませんでしたがそこを踏み込んで変更してくれました。
2. 環境変数とパッケージインストールの効率化
ENV LANG="C.UTF-8" TZ="UTC"
RUN apt update -qq && DEBIAN_FRONTEND=noninteractive apt -yq dist-upgrade &&\ DEBIAN_FRONTEND=noninteractive apt install -yq\ build-essential\ default-mysql-client\ ffmpeg\
ENV LANG="C.UTF-8" \ TZ="UTC" \ APP_HOME=/app \ LUA_LIB="/usr/lib/liblua5.1.so.0"
# Install system dependenciesRUN apt-get update -qq && \ DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade && \ DEBIAN_FRONTEND=noninteractive apt-get install -yq \ build-essential \ curl \ default-mysql-client \ ffmpeg \ liblua5.1-0 \ pandoc &&\ apt clean &&\ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* &&\ pandoc \ imagemagick \ libmagickwand-dev && \ ln -s /usr/lib/`uname -m`-linux-gnu/liblua5.1.so.0 ${LUA_LIB} && \ # Install Node.js curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ apt-get install -y nodejs && \ # Cleanup apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ truncate -s 0 /var/log/*log今までは人間が見やすいようにするメンテナナンス性や、build cacheを使うためにステップごとに処理をある程度区切っていましたが build layerを少なくするために1コマンドで色々行うように変更されました。
人間がメンテナンスしづらくはなりますが、LLM経由でメンテナンスできるならばこれで問題無いと思います。
ベースイメージのサイズ比較
サイズ削減の効果を調査するために、そもそもslimとそうでないイメージでどのくらいサイズの差があるのかを調べてみたら、5倍ちかく容量が違いました。
通常イメージ
❯ docker images ruby:3.4.1REPOSITORY TAG IMAGE ID CREATED SIZEruby 3.4.1 79e67c837851 5 weeks ago 1.01GBSlimイメージ
❯ docker images ruby:3.4.1-slimREPOSITORY TAG IMAGE ID CREATED SIZEruby 3.4.1-slim eb3ae63a0b49 8 weeks ago 219MB最終的な成果
最適化の結果
| 項目 | 最適化前 | 最適化後 | 削減率 |
|---|---|---|---|
| ベースイメージ | 1.0GB | 219MB | 78.1% |
| アプリケーションイメージ | 1.96GB | 1.75GB | 10.7% |
ベースイメージの大幅な軽量化により、全体で約250MB(約15%)のサイズ削減に成功しました。 これによりビルド時間の短縮やコンテナのpull時間改善など、CI/CDパイプライン全体の効率化につながりました。
(余談)Docker Gordonでの試み
Docker Desktopに統合されたAI機能(Gordon)も試してみましたが、現時点では正常に動作しませんでした。
設定を有効化し、規約に同意しても機能が利用できない状態でした。


本番環境へのデプロイ時の注意
このDockerfileの最適化を行った後、入念なテストを経て本番にデプロイしました。
1つだけ問題が発生しました。AWS ECSのhealthcheckにて ps コマンドによるsidekiqプロセスの有無をチェックしてhealthyかどうかを判定していました。
slim imageにはpsコマンドすら入っていなかったので別のコマンドでチェックするようにtask definitionsを変更しました。
cat /proc/*/cmdline | tr '\0' ' ' | grep sidekiq || exit 1まとめ
- イメージサイズを 15%削減(約 250MB)できました。
- すでにある程度はきれいにしているのでそんなに無駄は無いので 70%も削る余地が無かったです。
- ビルド時間の短縮と pull 時間の改善
- LLM を活用することで、従来は困難だった最適化作業を効率的に実施できた