BuildKitでイメージをビルドする
Dockerでコンテナイメージをビルドするときに、下記のようなことを考えていました。
- ビルド時間を短くしたい
- Raspberry Piでも動くコンテナイメージを作りたい
そこでBuildKitを使って、マルチプラットフォーム(multi-platform)のイメージを
マルチステージ(multi-stage)ビルドをすることにしました。
BuildKitについての説明をスキップしてビルド方法を知りたい場合は、
BuildKitとdocker-buildxプラグイン の章から読んでください。
BuildKitとは
BuildKit1 とは、コンテナをビルドするためのツールキットであり、buildkitd
というデーモンとbuildctl
コマンドで構成されています。
Dockerの標準のビルドと比べて、BuildKitでビルドした場合には以下のようなメリットがあります。
- マルチステージDockerfileの各ステージを並列ビルドできる
- ビルドキャッシュをDockerHubなどに外部保存/再利用ができる
- マルチプラットフォーム対応のイメージをビルドできる (2020年6月時点ではLinuxのみ)
- Dockerfile内のビルド時に実行するRUNコマンドで、新たな実験的機能を使用できる
- SSH接続でリモートのファイルを取得
- 秘密鍵などのファイルをイメージ内に残さないようにマウント など5
また、BuildKitの一部機能はDocker 18.06以降のDocker Engineに統合されており、
Docker単体でもBuildKitの一部機能を利用することができます。

buildkitd, buildctl を使用したビルド
BuildKitとdocker-buildxプラグイン
BuildKitを使用してビルドをするには、buildkitd
デーモンを起動してbuildctl
コマンドからビルドを実行できます。
しかし、既にDockerを使用しているのであれば、docker-buildx2 プラグインを利用することで、 下記の様なメリットがあります。
- ビルド時に、自動で
buildkitd
,buildctl
を含むコンテナを起動 - dockerコマンドと同じようなUIでビルドができる

docker-buildxプラグインをインストール
docker-buildx2 プラグインを利用するには下記の3点が必要です。
Docker CLIの実験的機能の有効化
docker-buildxは2020年6月時点では、まだ実験的機能と位置づけられているため、 docker CLIの設定で実験的機能を有効化する必要があります。docker-buildxプラグインのインストール (Docker for Linuxの場合)
Docker for Linuxを使用している場合は、GitHubのdocker/buildx のリリースページからバイナリをダウンロード、インストールします。
Docker Desktopの場合は、あらかじめインストールされています。qemu-user-staticのインストール (Docker for Linuxの場合)
マルチプラットフォームイメージをビルドする場合は、対応するアーキテクチャの実行環境が必要です。
今回は qemu-user-static をインストール6し、エミュレーション環境を用意します。
こちらもDocker Desktopの場合は、あらかじめインストールされています。
Docker DesktopのSettings画面で画面中央の「CLI Experimental」のトグルスイッチを有効にしてから 右下の「Apply & Restart」ボタンをクリックして反映します。
docker-buildx プラグインと qemu-user-static は、Docker Desktopに同梱されているため、インストール不要です。
実験的機能の有効化とdocker-buildxのインストール
# 実験的機能の有効化 (方法1: ~/.docker/config.jsonの編集)cp-p~/.docker/config.json{,.bk}&&\cat~/.docker/config.json.bk|dockerrun-i--rmalpine:latestsh-c\"apk add --no-cache jq > /dev/null \&& jq '. |= .+{\"experimental\": \"enabled\"}'">~/.docker/config.json# もしくは、# 実験的機能の有効化 (方法2: 環境変数'DOCKER_CLI_EXPERIMENTAL'を設定)exportDOCKER_CLI_EXPERIMENTAL=enabled# docker-buildxのインストールmkdir-p~/.docker/cli-plugins&&\dockerrun--rmalpine:latestsh-c\"apk add --no-cache curl jq > /dev/null \&& curl -sS https://api.github.com/repos/docker/buildx/releases/latest | \ jq -r '.assets[].browser_download_url' | grep linux-amd64 | xargs curl -sSL"\>~/.docker/cli-plugins/docker-buildx\&&chmoda+x~/.docker/cli-plugins/docker-buildx# buildxのバージョン表示確認dockerbuildxversion# qemu-user-staticのインストール (Ubuntu/Debian の場合)sudoaptinstallqemu-user-static# qemu-user-staticのインストール (Fedora の場合)sudodnfinstallqemu-user-static# もしくは、# qemu-user-staticのインストール (Dockerイメージを使う場合)dockerrun--rm--privilegedmultiarch/qemu-user-static--reset-pyes
ビルダーインスタンスの選択
docker-buildxプラグインでビルドする際には「ビルダーインスタンス」と呼ばれるものを使用します。
デフォルトではDocker Engine内のBuildKitを使用する'docker'ドライバのビルダーインスタンスを使用する設定になっています。
フル機能のBuildKitを利用する場合には、'docker-container' ドライバか 'kubernetes' ドライバのビルダーインスタンスを作成して使用します。
参考: ビルダーインスタンスのドライバの種類
ドライバ | ビルド実行方法 |
---|---|
docker | Docker Engineに統合されているBuildKitを使用してでビルド |
docker-container | buildkitd ,buildctl がインストールされたDockerコンテナを作成/起動してビルド |
kubernetes | buildkitd ,buildctl がインストールされたKubernetesのポッドを作成/起動してビルド |
Dockerコンテナのビルダーインスタンスでビルド実行
# コンテナドライバのビルダーインスタンスを作成、現在のインスタンスを切り替えるdockerbuildxcreate--driverdocker-container--namecontainer-builder--use# ビルダーインスタンスを確認 (container-builder の右に '*' が付いている)dockerbuildxlsNAME/NODEDRIVER/ENDPOINTSTATUSPLATFORMScontainer-builder*docker-containercontainer-builder0npipe:////./pipe/docker_engineinactivedefaultdockerdefaultdefaultrunninglinux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6# ビルダーインスタンスのコンテナを停止するdockerbuildxstop
docker-buildxでビルド
Docker Hubなどのレジストリに/から、ビルドキャッシュをインポート/エクスポートするには、--cache-from
,cache-to
オプションを使用します。
buildxで外部キャッシュ使用してビルドしてpush
# レジストリからビルドキャッシュインポートしてビルドし、# その後にレジストリへコンテナイメージとビルドキャッシュを別々に保存dockerbuildxbuild\--cache-from"type=registry,ref=username/repo_name:cache_tag_name"\--cache-to"type=registry,ref=username/repo_name:cache_tag_name"\--push--tagusername/repo_name:tag_name.
また、マルチプラットフォームイメージをビルドする場合は、--platform
オプションを使用します。
buildxでマルチプラットフォームイメージをビルドしてpush
# x86,x64,armv6,armv7,aarch64で利用できるイメージをビルドしてpushdockerbuildxbuild\--platformlinux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8\--push--tagusername/repo_name:tag_name.
参考: キャッシュタイプの一覧 (2020年6月時点)
キャッシュタイプ | 説明 |
---|---|
inlineタイプ | コンテナイメージにビルドキャッシュを埋め込んで、イメージと一緒にDockerHubなどのレジストリに保存します。 |
registryタイプ | コンテナイメージとビルドキャッシュを別々にして、DockerHubなどのレジストリに保存します。 イメージとキャッシュ保存先でリポジトリ名:タグ名が、同じ場合/異なる場合のどちらでもエクスポート/インポートが可能です。 |
localタイプ | ビルドを実行するローカルホスト上のファイルシステムにビルドキャッシュを保存します。 CIツールを使用してビルドキャッシュを保存する場合などに便利です。 |
最新の情報については、docker/buildxのドキュメンテーション を参照して下さい。
参考: プラットフォームの一覧 (2020年6月時点)
プラットフォーム名 | |
---|---|
linux/386 | Linux / Intel x86(32bit) アーキテクチャ |
linux/amd64 | Linux / Intel x86_64(64bit) アーキテクチャ |
linux/arm/v6 | Linux / ARM v6(32bit) アーキテクチャ |
linux/arm/v7 | Linux / ARM v6(32bit) アーキテクチャ |
linux/arm64/v8 | Linux / ARM v8(64bit) アーキテクチャ |
linux/mips64le | Linux / MIPS64 Little Endian(64bit) アーキテクチャ |
linux/ppc64le | Linux / 64-bit PowerPC Little Endian(64bit) アーキテクチャ |
linux/s390x | Linux / IBM S/390(64bit) アーキテクチャ |
windows/amd64 | Microsoft Windows / Intel x86_64(64bit) アーキテクチャ |
その他のBuildKitの利用方法
以降の章ではdocker-buildxプラグインを利用しないBuildKitでのビルド方法を説明します。
Dockerを使用せず、buildkitdとbuildctlでビルドする
Dockerを使用せずにビルドするには、BuildKitのインストールが必要です。 以下の手順でインストールし、デーモンを起動します。
BuildKitをインストールし、buildkitdデーモンを起動
# BuildKitをインストールdockerrun--rmalpine:latestsh-c\"apk add --no-cache curl jq > /dev/null \&& curl -sS https://api.github.com/repos/moby/buildkit/releases | \ jq -r '.[].assets[].browser_download_url' | \ grep linux-amd64 | head -n 1 | xargs curl -sSL"|\sudotarzxf--C/usr/local/# buildkitdデーモンを起動sudobuildkitd
buildctlコマンドでビルド
# buildctlコマンドでビルド実行sudobuildctlbuild--frontend=dockerfile.v0--localcontext=.--localdockerfile=.
Docker EngineのBuildKitでビルド
BuildKitやdocker-buildxプラグインをインストールせず、 Docker 18.06以降のDocker Engineに統合されているBuildKitでビルドします。
BuildKitの有効化
# Docker統合のBuildKit有効化 (方法1: 設定ファイルに追記し、Docker Engineを再起動)(test-f/etc/docker/daemon.json&&cat/etc/docker/daemon.json||echo"{}")|\jq'. |= .+{"features": {"buildkit": true}}'|sudotee/etc/docker/daemon.jsonsudosystemctlrestartdocker.servie# または、# Docker統合のBuildKit有効化 (方法2: 環境変数'DOCKER_BUILDKIT'を設定)exportDOCKER_BUILDKIT=1# ビルド実行dockerbuild.
1つめの方法では、/etc
配下の設定ファイルの編集とデーモンの再起動を行うため、root権限が必要になります。
root権限が取得できない場合や、一時的にBuildKitを利用する場合は、環境変数での設定を試してください。
Docker EngineのBuildKitで利用できる機能
2020年6月時点で、Docker 18.06以降のDocker Engineに統合されているBuildKitでは
利用できない機能がいくつかあります。
それぞれで利用できる機能の差については、下記の表を参照してください。
機能 | Docker Engine 統合版 | buildkitd デーモン版 | 説明 |
---|---|---|---|
マルチステージビルドの並列実行 | ✅ | ✅ | マルチステージDockerfileの各ステージのビルドを可能な限り並列で実行します。 |
マルチプラットフォーム対応のイメージビルド | -- | ✅ | Intel(一般的なPC/サーバ)やArm(Raspberry Piなど)の複数のアーキテクチャで利用できるDockerイメージをビルドします。 |
ビルドキャッシュの出力 inlineタイプ | ✅ | ✅ | ビルドキャッシュをイメージに埋め込み、DockerHubなどのレジストリに保存します。 マルチステージビルドの場合は、最終的にコマンドが実行されるステージのキャッシュのみが保存されます。 |
registryタイプ | -- | ✅ | ビルドキャッシュとイメージを分けて、DockerHubなどのレジストリに保存します。 マルチステージビルドの場合、全てのステージのキャッシュを保存できます。 |
localタイプ | -- | ✅ | OCIイメージフォーマットに準拠した形式で、ローカルディレクトリにビルドキャッシュを保存します。 マルチステージビルドの場合、全てのステージのキャッシュを保存できます。 |
ビルドキャッシュの使用 registryタイプ | ✅ | ✅ | DockerHubなどのレジストリから、inline形式/egistry形式のビルドキャッシュを取得します。 |
localタイプ | -- | ✅ | ローカルディレクトリから、local形式のビルドキャッシュを取得します。 |
Composeファイルでのビルド | -- | ✅ | docker-compose.ymlファイルからDockerfileやビルドコンテキストを読み取ってビルドします。 |
Dockerfileの実験的機能の使用 | ✅ | ✅ | ビルドステップ単位で、パッケージマネージャのキャッシュ(--mount tyle=cache)や認証情報(--mount type=secret)をマウントしたり、ネットワークの制御(--network=none|host|default)などができます。 詳細はGitHub上のドキュメント を参照してください。 |
moby/buildkit: concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit ↩
docker/buildx: Docker CLI plugin for extended build capabilities with BuildKit · GitHub ↩↩
Docker Blogでのマルチプラットフォームビルドの解説Multi-arch build and images, the simple way - Docker Blog ↩
Dockerfileの実験的機能についてはDockerfile frontend experimental syntaxes - buildkit/experimental.md GitHub を参照。 ↩
各ディストリビューションに応じたパッケージマネージャ、またはmultiarch/qemu-user-static - Docker Hub のDockerイメージを使用してインストールしてください。 ↩