1187 文字
6 分

LLMを活用してDockerfileを最適化し15%のサイズ削減を実現した話

3行まとめ#

  • LLM を活用して Dockerfile のリファクタリングを実施し、イメージサイズを 15%削減(1.96GB → 1.75GB)
  • LLM 登場前に書いたコードを LLM にリファクタさせるのは良い結果を生む(最近これが楽しい)
  • slim イメージへの移行とパッケージ最適化により、ビルド時間と pull 時間を改善

背景#

長年運用している Dockerfile は複雑化していく傾向にあります。

リファクタリングはリグレッションのリスクがあり、手を出しづらいです。

最近、Devin による Dockerfileリファクタリングの成功事例を見て、自プロジェクトでも試してみることにしました。

最適化前の状態#

まず、変更前の Docker image のサイズを調べておきます。

Terminal window
docker images minedia-www-app
REPOSITORY TAG IMAGE ID CREATED SIZE
minedia-www-app latest 7e88a3086cb9 4 days ago 1.96GB

2GBありました。

アプローチ#

Devinにやってもらおうかと思いましたが、そもそもこんなDockerfileのリファクタだったらClineで十分だと思うのでClineでClaude sonnet 3.5(少し前に行ったので古い)で実行してみました。

プロンプトは、ラフに「Dockerfileをリファクタリングして」という指示だけです。

LLMによる主要な変更点#

1. ベースイメージの最適化#

FROM ruby:3.4.1
FROM 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 dependencies
RUN 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倍ちかく容量が違いました。

通常イメージ#

Terminal window
docker images ruby:3.4.1
REPOSITORY TAG IMAGE ID CREATED SIZE
ruby 3.4.1 79e67c837851 5 weeks ago 1.01GB

Slimイメージ#

Terminal window
docker images ruby:3.4.1-slim
REPOSITORY TAG IMAGE ID CREATED SIZE
ruby 3.4.1-slim eb3ae63a0b49 8 weeks ago 219MB

最終的な成果#

最適化の結果#

項目最適化前最適化後削減率
ベースイメージ1.0GB219MB78.1%
アプリケーションイメージ1.96GB1.75GB10.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 を活用することで、従来は困難だった最適化作業を効率的に実施できた
LLMを活用してDockerfileを最適化し15%のサイズ削減を実現した話
https://blog.teraren.com/posts/dockerfile-refactoring-by-llm/
作者
Yuki Matsukura
公開日
2025-03-25
ライセンス
CC BY-NC-SA 4.0
この記事が役に立ったら
GitHub Sponsorsで応援できます

コメント