概要
Dockerfileにてコンテナイメージを作成する際、イメージサイズを削減することが一つのポイントとなってきます(コンテナの起動時間を短縮するため)。イメージサイズの削減を単純に実施するには、レイヤ数を削減することが手っ取り早いですが、これを多用すると保守性が下がってしまいます。
Dockerfileではイメージサイズの削減を目的にマルチステージビルドという実装方法があります。
デプロイ対象のイメージと別にビルド用のイメージを生成し、ビルド用のイメージ内で生成したコンポーネントをデプロイ対象のイメージにコンテンツをコピーしデプロイ対象のイメージサイズを削減することが可能です。
例えば、ビルド用のイメージにてyumでパッケージをインストールし、実行ファイルのみをデプロイ対象のイメージへコピーする、といったことが可能です。
これにより、yumでパッケージをインストールするよりもデプロイ対象のイメージを削減することができます。
使ってみた
本記事では、AmazonLinux2のベースにJDK(AmazonCorretto)をインストールしたコンテナイメージを生成します。これをマルチステージビルドを使わない場合、使う場合でイメージサイズの比較を行います。
FROM public.ecr.aws/amazonlinux/amazonlinux:2
# JDKインストール
RUN yum -y install java-11-amazon-corretto-headless
# build-stage
FROM public.ecr.aws/amazonlinux/amazonlinux:2 as build-stage
# JDKインストール
RUN yum -y install java-11-amazon-corretto-headless
# Deploy
FROM public.ecr.aws/amazonlinux/amazonlinux:2
# コピー先のディレクトリを作成
RUN mkdir -p /usr/lib/jvm/java-11-amazon-corretto.x86_64/
# JDK(headless)をコピー
COPY --from=build-stage /usr/lib/jvm/java-11-amazon-corretto.x86_64/ /usr/lib/jvm/java-11-amazon-corretto.x86_64/
# javaコマンドを利用するためのシンボリックリンクの作成
RUN ln -s /usr/lib/jvm/java-11-amazon-corretto.x86_64/bin/java /usr/bin/java
マルチステージビルド補足:
ビルド用イメージはFrom句にasを付与しビルドイメージ名を指定します。
FROM public.ecr.aws/amazonlinux/amazonlinux:2 as build-stage
ビルド用イメージの生成物を利用するためには、COPY句に--from=<ビルドイメージ名>という感じで指定します。
COPY --from=build-stage ・・・
なお、asの指定がない場合、数値になります。(0,1・・・)
この場合、"COPY --from=0"のような感じになります。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
not-multi v01 76f28683e68d 14 minutes ago 852MB
multi v01 9ec10bdf41bc 4 seconds ago 484MB
マルチステージビルドを利用した場合、約40%のイメージサイズ削減になりました。
まとめ
マルチステージビルドは学習コストがかかりますが、利用することでイメージサイズを削減することができる方法です。