マルチステージビルドとは
-
Dockerfile
に複数のFROM
命令を書く事で、命令単位で独立したステージとして扱われるビルド手法 - 独立したステージ群が直列にビルドされ、必要なファイルのみがコピーされることで最終的なイメージサイズを削減できる
マルチステージビルド時の挙動について
- 複数ステージが存在しても、最終的にイメージにビルドされるのは単一のステージのみ
-
docker image build
は--target
オプションでイメージ化するステージを指定する
--target
オプションが指定されない場合、Dockerfile内で定義された最後のステージが
暗黙的にイメージ化の対象になる - 直列にビルドされるステージ群は指定したステージが依存するステージ群のみ
マルチステージビルドを図解する(イメージサイズ)
-
具体例: 図の場合は
gcc
のイメージとubuntu
のイメージの二つのイメージで
マルチステージビルドを行う
図解をDockerfileで表す(数字参照)
FROM gcc:12.2.0
WORKDIR /app
COPY ./hello.c .
RUN gcc hello.c
FROM ubuntu:20.04
WORKDIR /app
COPY --from=0 /app/a.out .
CMD ["./a.out"]
-
COPY --from=0
は0番目のステージを参照する
図解をDockerfileで表す(名前参照)
FROM gcc:12.2.0 AS compiler
WORKDIR /app
COPY ./hello.c .
RUN gcc hello.c
FROM ubuntu:20.04
WORKDIR /app
COPY --from=compiler /app/a.out .
CMD ["./a.out"]
-
FROM {イメージ名} AS {ステージ名}
でステージに名前を付ける -
COPY --from={ステージ名}
で該当ステージを参照する
マルチステージビルドを図解する(共通処理の分離)
-
具体例: 図の場合は
ubuntu
のベースイメージへの処理は共通で行い、環境に依存する処理はステージを分けて行う
--targetを利用した共通処理と環境依存処理の分離
-
--target
オプションによってビルドに利用されるステージが変更されることを利用し、最終的にビルドされるイメージを変更している - 最終的にビルドに指定されるステージが依存しているステージを直列にビルドしていく
また、依存が無ければビルドしない
targetオプションで実行環境を変更する
FROM ubuntu:20.04 AS base
RUN apt update
CMD ["sh", "-c", "echo My name is $my_name"]
FROM base AS development
ENV my_name="TEST"
FROM base AS production
ENV my_name="Prod"
target:development
docker image build --target development . # base + development
-
container run
->echo "My name is TEST"
target:production
docker image build --target production . # base + production
-
container run
->echo "My name is Prod"