なぜ、ビルドを早くする
- デプロイ時間の短縮
- AutoScaling 等でのインスタンスの追加時間の短縮
- CI のビルド時間が短縮
どう、ビルドを早くする
- 並列性を上げる
- ビルドキャッシュを効かせる
並列性
本記事では、並列性のみに触れる。
BuildKit を使用する
Docker 18.09 のリリースにおいて行われたビルド機能の拡張は、ビルドアーキテクチャーの総見直しにより必要となる機能を導入しています。 BuildKit を統合したことによって、処理性能、ストレージ管理、ツール機能、セキュリティのどれをとっても改善が見られるはずです。 https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/build_enhancements/
$ DOCKER_BUILDKIT=1 docker build .
のように環境変数にセットすることで Builtkit を利用したビルドをすることができる。
また、AWS CodeBuildでもBuildKitをサポートしている。
簡単な例
簡単な例で確かめてみる。
以下のDockerfile
に対して、DOCKER_BUILDKIT=1 docker build .
を実行すると、① が同時に実行される。
FROM alpine as test1 RUN sleep 1 # ① FROM alpine as test2 RUN sleep 2 # ① FROM alpine as test3 RUN sleep 3 # ① FROM alpine as test4 RUN sleep 4 # ① FROM alpine RUN sleep 5 # ① COPY --from=test1 /bin /bin COPY --from=test2 /bin /bin COPY --from=test3 /bin /bin COPY --from=test4 /bin /bin RUN sleep 6
前記事の例
修正前
Go製CLIツールを使うDockerイメージをダイエットしてみた - 🤖
前記事では、イメージサイズを意識したDockerfileを書くことはできたが、実行時間については意識していなかった。 前記事のDockerfile では Alpine のステージの最初で Builder のステージに依存しているため、並列実行を行うことができない。
FROM golang as builder RUN CGO_ENABLED=0 go get github.com/tenntenn/qiitaexporter github.com/x-motemen/blogsync FROM alpine # ここで既にbuilderステージに依存しており並列実行できない COPY --from=builder /go/bin/qiitaexporter /bin/qiitaexporter COPY --from=builder /go/bin/blogsync /bin/blogsync RUN apk --no-cache add libintl && \ apk --no-cache add --virtual .gettext gettext && \ cp /usr/bin/envsubst /usr/local/bin/envsubst && \ apk del .gettext WORKDIR /Documents COPY blogsync.template /Documents COPY setup.sh /Documents RUN mkdir -p ~/.config/blogsync COPY config.yaml.tmp /root/.config/blogsync RUN chmod +x setup.sh ENTRYPOINT ./setup.sh
修正後
修正後の Dockerfile では、① で示された三箇所は並列実行される。
しかしgo get
を二つに分け並列処理を行ったが、ビルド時間を大きく減らすことはなかった。
それはおそらく、go get github.com/tenntenn/qiitaexporter github.com/x-motemen/blogsync
が内部では並列実行されているからではと思った。
FROM golang as qiitaexporter-builder RUN CGO_ENABLED=0 go get github.com/tenntenn/qiitaexporter # ① FROM golang as blogsync-builder RUN CGO_ENABLED=0 go get github.com/x-motemen/blogsync # ① FROM alpine # ①Start WORKDIR /Documents COPY blogsync.template /Documents COPY setup.sh /Documents RUN chmod +x setup.sh RUN mkdir -p ~/.config/blogsync COPY config.yaml.tmp /root/.config/blogsync RUN apk --no-cache add libintl && \ apk --no-cache add --virtual .gettext gettext && \ cp /usr/bin/envsubst /usr/local/bin/envsubst && \ apk del .gettext # ①End # 以下はbuilderステージに依存しているため並列実行されない COPY --from=qiitaexporter-builder /go/bin/qiitaexporter /bin/qiitaexporter COPY --from=blogsync-builder /go/bin/blogsync /bin/blogsync ENTRYPOINT ./setup.sh
おわりに
並列性の具体例を紹介していると、記事として分量が多くなったため、ビルド時のキャッシュについては今度改めて紹介する。