1
0

【Dockerfile】RUN命令の`--mount`オプションを活用して、コンテナイメージのサイズを削減する

Last updated at Posted at 2024-06-07

DockerfileのRUN命令には、--mountというオプションがあります
https://docs.docker.com/reference/dockerfile/#run---mount

このオプションで指定したディレクトリで行った作業は、最終的なコンテナイメージには反映されません
また、このディレクトリはマルチステージビルド時にコンテナ間で共有することも可能です
この記事では、--mountオプションを利用してこのようなリソースを、最終的なコンテナのイメージサイズに反映させないようにする方法を紹介します

  • aptなどパッケージマネージャーのキャッシュ
  • ビルドに必要で、実行時には不要なソースコードやファイル
  • gitやwgetなどの、ファイルダウンロード用のパッケージ

1. aptなどパッケージマネージャのサイズ削減

ドキュメントに載っている例となりますが、実際にどのくらいの削減を見込めるのか、見てみます
https://docs.docker.com/reference/dockerfile/#run---mounttypecache

ベースイメージ

今回はubuntu 24.04で検証します
容量は136MBです

$ docker image ls ubuntu:24.04
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       24.04     3f85b7caad41   4 weeks ago   136MB

apt update

パッケージを更新するだけでどのくらいサイズが増えるか確認します

FROM ubuntu:24.04
RUN apt-get update
$ docker build -t dockerfile-run-mount:apt .
$ docker image ls dockerfile-run-mount:apt
REPOSITORY             TAG       IMAGE ID       CREATED       SIZE
dockerfile-run-mount   apt       8b9733505c07   3 hours ago   197MB

61MB増加の197MBでした

パッケージをインストール

makeをインストールしてみます

FROM ubuntu:24.04
RUN apt-get update && apt-get install --no-install-recommends -y make
$ docker build -t dockerfile-run-mount:make .
$ docker image ls dockerfile-run-mount:make
REPOSITORY             TAG       IMAGE ID       CREATED       SIZE
dockerfile-run-mount   make      6b118565e1b4   2 hours ago   198MB

makeをインストールすると1MB増えました

cacheを使用してパッケージをインストール

公式ドキュメントの通り、RUN命令にオプションを追加します

FROM ubuntu:24.04
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
	--mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && apt-get install --no-install-recommends -y make

二つのディレクトリに対して、オプションが設定されています

  • /var/cache/apt
  • /var/lib/apt

オプション内容は同一です

--mount=type=cache,target={ディレクトリ名},sharing=locked
  • target={ディレクトリ名}
    マウント先ディレクトを指定します
    このディレクトリに対して行った作業は、コンテナイメージ内に残りません
  • sharing=locked
    複数の命令から書き込みできないようにする設定です
    今回はapt用のキャッシュは他では使用しないですが、マルチステージビルド内でキャッシュを共有する場合には設定が必要になります

この状態でコンテナをビルドします

$ docker build -t dockerfile-run-mount:cache .
$ docker image ls dockerfile-run-mount:cache
REPOSITORY             TAG       IMAGE ID       CREATED       SIZE
dockerfile-run-mount   cache     ad9befef2bfd   2 hours ago   137MB

ビルド後のサイズは137MBと、ubuntu:24.04からmake分の1MB増えただけです
cacheオプションの効果で、apt updateの分だけサイズ削減できました

2. ソースコードからビルドする際のサイズ削減

コンテナ内で使うライブラリを、ソースコードからビルドしないといけないケースでの活用例です
モダンなプログラミング言語のライブラリであれば気にしなくていいですが、makeのプロジェクトではサイズ削減が見込める手法です
※必要なパッケージが足りていないので、下記のコードではopensslはビルドできません

FROM ubuntu:24.04 as src
WORKDIR /usr/local/src
RUN apt-get update && apt-get install --no-install-recommends -y git
RUN git clone --depth 1 https://github.com/openssl/openssl.git

FROM ubuntu:24.04
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
	--mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && apt-get install --no-install-recommends -y \
    make
RUN --mount=type=cache,target=/usr/local/src,from=src,source=/usr/local/src cd /usr/local/src/openssl \
    && ./Configure \
    && make \
    && make install

マルチステージビルドを使用し、二つの点でサイズ削減を行なっています

ソースコードフォルダ自体を、本番コンテナから分離する

--mountオプションの--type=cacheでは、マルチステージビルドの別コンテナからディレクトリをマウントすることが可能です
上記のDockerfileでは、ソースコード用のコンテナを実行用コンテナとは別に用意し、ソースコードはそちらに展開するようにしています

--mount=type=cache,target=/usr/local/src,from=src,source=/usr/local/src

これにより、実行用コンテナにソースコードをコピーすることなく、実行用コンテナ内でビルドが可能です

ソースコードを取得するためのパッケージ

gitやwgetなど、ソースコードをコンテナ内に持ってくるためのコマンドは、実行用のコンテナ内では不要なことが多いと思います
マルチステージビルドで、ソースコードを取得するためのコンテナを別で定義し、実行用コンテナではソースコードはマウントするのみとしています

FROM ubuntu:24.04 as src
WORKDIR /usr/local/src
RUN apt-get update && apt-get install --no-install-recommends -y git
RUN git clone --depth 1 https://github.com/openssl/openssl.git

FROM ubuntu:24.04
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
	--mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && apt-get install --no-install-recommends -y \
    make
RUN --mount=type=cache,target=/usr/local/src,from=src,source=/usr/local/src cd /usr/local/src/openssl \
    && ./Configure \
    && make \
    && make install

まとめ

コンテナのイメージサイズを削減する手段として、RUN命令の--mountオプションを紹介しました
今回マウントタイプはcacheのみ例示しましたが、他にはtmpfsも有用です
https://docs.docker.com/reference/dockerfile/#run---mounttypetmpfs

dockerコンテナはその仕組み上、一度ダウンロードしたソースコードを以降のRUN命令で削除しても、最終的なイメージサイズの削減にはなりません
実行用のコンテナにいかに不要ファイルを入れないかが重要です

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0