Dockerのマルチステージビルドを試す

概要

Docker 17.05以降でマルチステージビルドという機能が追加された。

matsuand.github.io

この機能を利用すると

  • イメージサイズが小さくなる
  • 保守が簡単
  • 可読性が上がる

ということらしい。
そこで実際に自分でDockerファイルを書いてイメージファイルがどれくらい小さくなるのか確認してみる。
確認方法はマルチステージビルドを利用して書いたDockerファイルと利用しないで書いたDockerファイルの2つのDockerファイルを書いてイメージファイルのサイズを比較する。

環境

Docker v19.03.12

Dockerで構築する環境

今回はPyKNPの環境を構築する。

PyKNPについて

PyKNPは京大がオープンにしている形態素解析器Juman、述語項構造解析器KNPのバインディングしたPythonのモジュール。
このため、先にJumanとKNPをインストールしておく必要がある。

Dockerファイル

今回のベースとするDockerイメージはpython slimdebianを使う。
マルチステージビルドを使ってないDockerファイルにはpython slimをベースとして構築する。
マルチステージビルドを使ったDockerファイルにはdebianで先に環境を構築してから、python slimにコピーする。
イメージファイルを区別するために前者をtest_1、後者をtest_2という名前にしてからビルドする。

test_1

FROM python:3.6-slim
ENV JUMAN_VERSION 2.0.0-rc3
ENV JUMAN_DIR jumanpp-${JUMAN_VERSION}
ENV JUMAN_URL https://github.com/ku-nlp/jumanpp/releases/download/v${JUMAN_VERSION}/jumanpp-${JUMAN_VERSION}.tar.xz
ENV KNP_VERSION 4.20
ENV KNP_DIR knp-${KNP_VERSION}
ENV KNP_URL http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/knp/${KNP_DIR}.tar.bz2
RUN apt update && \
    apt -y upgrade && \
    apt install -y --no-install-recommends \
    gcc \
    g++ \
    make \
    cmake \
    xz-utils \
    bzip2 \
    libz-dev \
    wget && \
    echo "${JUMAN_URL}" && \
    wget -q --no-check-certificate ${JUMAN_URL} -O ${JUMAN_DIR}.tar.xz && \
    tar -Jxvf ${JUMAN_DIR}.tar.xz && \
    rm ${JUMAN_DIR}.tar.xz && \
    cd ${JUMAN_DIR} && \
    mkdir bld && \
    cd bld && \
    cmake .. -DCMAKE_BUILD_TYPE=Release && \
    make install -j 4 && \
    cd ../.. && \
    echo "jumanpp install done" && \
    echo "${KNP_URL}" && \
    wget -q --no-check-certificate ${KNP_URL} -O ${KNP_DIR}.tar.bz2 && \
    tar jxvf ${KNP_DIR}.tar.bz2 && \
    rm ${KNP_DIR}.tar.bz2 && \
    cd ${KNP_DIR} && \
    ./configure && \
    make && \
    make install && \
    echo "KNP install done" && \
    pip install pyknp && \
    apt clean && \
    rm -rf /var/lib/apt/lists/*

test_2

FROM debian as builder
ENV JUMAN_VERSION 2.0.0-rc3
ENV JUMAN_DIR jumanpp-${JUMAN_VERSION}
ENV JUMAN_URL https://github.com/ku-nlp/jumanpp/releases/download/v${JUMAN_VERSION}/jumanpp-${JUMAN_VERSION}.tar.xz
ENV KNP_VERSION 4.20
ENV KNP_DIR knp-${KNP_VERSION}
ENV KNP_URL http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/knp/${KNP_DIR}.tar.bz2
RUN apt update && \
    apt -y upgrade && \
    apt install -y --no-install-recommends \
    gcc \
    g++ \
    make \
    cmake \
    xz-utils \
    bzip2 \
    libz-dev \
    wget && \
    echo "${JUMAN_URL}" && \
    wget -q --no-check-certificate ${JUMAN_URL} -O ${JUMAN_DIR}.tar.xz && \
    tar -Jxvf ${JUMAN_DIR}.tar.xz && \
    rm ${JUMAN_DIR}.tar.xz && \
    cd ${JUMAN_DIR} && \
    mkdir bld && \
    cd bld && \
    cmake .. \
    -DCMAKE_BUILD_TYPE=Release && \
    make install -j 4 && \
    cd ../.. && \
    echo "jumanpp install done" && \
    echo "${KNP_URL}" && \
    wget -q --no-check-certificate ${KNP_URL} -O ${KNP_DIR}.tar.bz2 && \
    tar jxvf ${KNP_DIR}.tar.bz2 && \
    rm ${KNP_DIR}.tar.bz2 && \
    cd ${KNP_DIR} && \
    ./configure && \
    make && \
    make install && \
    echo "KNP install done"

FROM python:3.6-slim as runner
COPY --from=builder /usr/local /usr/local
RUN pip install pyknp

結果

docker imagesコマンドラインで打って確認。

f:id:seven_901:20200907114306p:plain

結果だけ見ると、イメージファイルのサイズがマルチステージビルドを利用すると1/3になっている。

まとめ

マルチステージビルドを利用したらイメージファイルが軽くなった。