Docker 17.05から、新機能としてmulti-stage builds というものが導入されました。 これは、コンテナイメージをより最適化するために有用な機能で、Dockerfileからコンテナイメージをビルドする際にビルド依存のライブラリ/環境とランタイム依存のライブラリ/環境を切り分けることができる機能です。
具体例を見てみましょう。 Go言語で書かれた何らかのアプリケーションをコンテナ上で動かすことを考えます。 以前までであれば、以下のような二つのDockerfileを用いて作成します。
まずはビルド用Dockerfileです
|
|
つぎに、実行用のDockerfileです。
|
|
このようにすることで、ビルド時にはGo言語のビルド環境が入ったコンテナを、実行時は(Go言語環境は不要なので)busyboxコンテナを使用することで、実行イメージを小さく抑えることができます。 しかし、このように二つのDockerfileを使用する場合、コンテナイメージのビルド手順が煩雑になる、複数ファイルのため管理しにくいなどの問題がありました。
multi-stage buildsを実装されたことで、以下のようにDockerfileを一つにまとめることができます。
|
|
一行目のAS build
、九行目の--from=build
がポイントです。
AS hoge
を使用することで、ビルドステージに名前をつけることができます。
加えて、COPY
に--from=hoge
の形で名称を指定することで、ビルドステージから直接ファイルをコピーしてくることができます。
これまでは一旦ホストにファイルを取り出してから再度コピーするという形だったので、かなり手間が省けると言えるでしょう。
golangイメージの中でも小さい、golang:alpine
とbusybox
イメージでは、イメージサイズが200倍以上違うため、これは重要なアップデートと考えられます。