初期の Docker には存在しなかった、マルチステージビルドおよび buildkit を利用すると、イメージのビルドを効率化できます。
マルチステージビルド
バージョン 17.05 以降で利用できます。Docker イメージのサイズを小さくするためには、イメージのレイヤを少なくすることが有効です。過去のバージョンの Docker では、まず最初にアプリケーションビルド用の Dockerfile でイメージをビルドして、ビルドしたイメージから docker create
してビルド成果物などを取り出し、別の Dockerfile で改めてイメージをビルドする、ということを外部のシェルスクリプトなどで行っていました。このような手順でレイヤを少なくする方法は builder pattern とよばれました。マルチステージビルドを用いると、同様のことが一つの Dockerfile だけで実現できます。以下はマルチステージビルドの例です。
CMakeLists.txt
cmake_minimum_required (VERSION 3.10)
add_executable(main main.cpp)
main.cpp
#include <iostream>
int main() {
std::cout << "hi" << std::endl;
return 0;
}
Dockerfile
FROM amd64/gcc:latest AS mybuilder
RUN apt update
RUN apt install -y cmake
RUN mkdir -p /work/build
COPY CMakeLists.txt /work/
COPY main.cpp /work/
WORKDIR /work/build
RUN cmake ..
RUN make
FROM debian:buster-slim
COPY --from=mybuilder /work/build/main /usr/local/bin/myapp
CMD ["myapp"]
ビルド例
docker build -t myapp:latest .
docker run --rm myapp:latest
hi
特定のステージまでをビルドすることもできます。
docker build --target mybuilder -t mybuilder:latest .
docker run --rm mybuilder:latest /work/build/main
hi
サイズおよびレイヤ数に大きな違いがあることが確認できます。
$ docker image ls myapp
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp latest af9aea1fedf7 2 minutes ago 69.2MB
$ docker image ls mybuilder
REPOSITORY TAG IMAGE ID CREATED SIZE
mybuilder latest 317ea3a9255c 2 minutes ago 1.18GB
$ docker history myapp | wc -l
5
$ docker history mybuilder | wc -l
23
DOCKER_BUILDKIT
バージョン 18.09 利用できる buildkit は既定では有効になっておらず、環境変数を設定すると有効になります。
DOCKER_BUILDKIT=1 docker build -t myapp:latest .
有効にした状態であれば、ssh などの認証情報を Dockerfile 内で syntax=docker/dockerfile:experimental
の拡張記法で利用できます。
# syntax=docker/dockerfile:experimental
FROM alpine:latest
RUN apk add --no-cache openssh-client git
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh git clone git@github.com:xxx/xxx.git
ビルド例
DOCKER_BUILDKIT=1 docker build --ssh default .
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- RancherOS で構築した k8s クラスタ用に GlusterFS で簡単な分散ファイルシステムを構築k8s クラスタの各 Node マシンに GlusterFSサーバのコンテナを一つだけ起動して、簡単な分散ファイルシステムを構築します。各 Node へのコンテナ設置のためには DaemonSet が利用できそうですが、ここでは RancherOS の rancher.services を利用します。 1台構成 後に `rancher.ser
- Rancher で構築した kubernetes クラスタのアップグレード手順RancherOS 等、docker が使える何らかの OS で Rancher によって構築した kubernetes クラスタのアップグレードを行うためには、以下のようにします。 v2.1.5 の Rancher で構築した k8s クラスタに存在する脆弱性 CVE-2019-11253 への対応がなされた [v2.3.2](https://github.com
- Docker CLI チートシートDocker に関するコマンド逆引き集です。公式ページの「Reference documentation」情報をもとにしています。 Docker 用語について コンテナ 後述のイメージという型をもとに作られる実体です。例えるならば、オブジェクト指向プログラミングにおけるクラスが Docker イメージで、インスタンスが Docker コンテナです。ある
- 複数の物理ホストの Debian9 上に Kubernetes (k8s) クラスタを Rancher で立ち上げるDocker オーケストレーションツールの一つに Kubernetes (k8s) があります。k8s 実行環境の構築方法は複数ありますが、ここでは AWS や GCP 等のクラウドサービスを利用せず、Debian9 がインストールされた複数台の物理マシンがネットワーク内に存在する状況を考えます。これら複数の Debian9 上に k8s クラスタを立ち上げるためには [Ranche
- Dockerfile ベストプラクティス (仮)Dockerfile を書く際に気になるポイント集です。「Best practices for writing Dockerfiles」および「Dockerfile Reference」をもとにしています。 Dockerfil