
2026/02/26 23:05
**BuildKit:Docker の隠れた宝石 ― ほぼすべてを構築可能**
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
BuildKitは汎用的でプラグイン可能なビルドエンジンで、DockerイメージだけでなくOCIイメージ、tarball、ローカルディレクトリ、APKパッケージ、RPMなど多様なアーティファクトを生成できます。これはそのコア言語であるLLBのおかげです。LLBはファイルシステム操作をコンテンツアドレス可能なDAGとして表現します。同一の操作は同じハッシュ値になるため、ソルバーはすでに構築済みのステップをスキップし、独立したブランチを並列に実行できます。これによりビルドが高速かつ再現可能になります。
フロントエンドはさまざまなビルド言語(Dockerfile、YAML、JSON、HCL、カスタムDSL)をLLBへ変換するコンテナイメージです。Dockerfileの
syntax: ディレクティブで実行するフロントエンドイメージを選択し、BUILDKIT_SYNTAX ビルド引数は docker buildx と組み合わせて上書きし、カスタムフロントエンドを呼び出すことができます。
Earthly、Dagger、Depot などのプロジェクトは既に BuildKit の LLB を内部で使用しています。カスタム
apkbuild フロントエンドは、Dockerfile を書かずにシンプルな YAML スペックから Alpine APK パッケージを生成する方法を示しています:イメージをビルドします(docker build -t tuananh/apkbuild .)その後実行
docker buildx build \ --build-arg BUILDKIT_SYNTAX=tuananh/apkbuild \ --output type=local,dest=./out \ -f spec.yml .
出力は直接
./out に書き込まれ、コンテナイメージは作成・プッシュされません。
ビルトインのキャッシング、並列処理、および再現性を公開することで、BuildKit は開発者が任意のアーティファクトタイプ用に新しいフロントエンドを書きやすくします。これらのコア機能を再実装せずに済むため、より効率的な CI/CD パイプライン、画像肥大化の抑制、および多様なローカル/レジストリアーティファクトが最小限のオーバーヘッドで可能になります。
本文
投稿日:2026年2月25日
ほとんどの人は、気づかぬうちに毎日 BuildKit と関わっています。
docker build を実行するとき、その背後で動いているのが BuildKit です。しかし「BuildKit は Dockerfile をビルドするもの」とだけ言ってしまうと、LLVM が「C をコンパイルするもの」と呼ばれるような、アーキテクチャを大幅に過小評価してしまいます。
BuildKit は汎用的でプラグ可能なビルドフレームワークです。
OCI イメージの生成はもちろんですが、tarball、ローカルディレクトリ、APK パッケージ、RPM など、ファイルシステム操作を有向非巡回図(DAG)で表せるものなら何でも作れます。Dockerfile はそのフロントエンドの一つにすぎず、自分で好きな言語を書いても構いません。
アーキテクチャ
BuildKit の設計は、レイヤーを見ればシンプルで驚くほど理解しやすいものです。主要な概念は三つあります。
LLB:中間表現
BuildKit の中心にあるのが LLB(Low‑Level Build definition)です。ビルドシステムの LLVM IR と考えてください。LLB はバイナリプロトコル(protobuf)で、ファイルシステム操作を有向非巡回図として記述します:コマンド実行、ファイルコピー、ファイルシステムのマウントなど。内容アドレス可能であるため、同一の操作は同一ハッシュになり、積極的なキャッシングが可能です。
Dockerfile を書くと、Dockerfile フロントエンドがそれを解析し LLB を生成します。しかし BuildKit には Dockerfile が必須というわけではなく、有効な LLB を作成できるプログラムなら何でもビルドを駆動できます。
フロントエンド:自分で構文を持ってくる
フロントエンドは、BuildKit が実行してビルド定義(Dockerfile、YAML、JSON、HCL など)を LLB に変換するコンテナイメージです。フロントエンドは BuildKit Gateway API を通じてビルドコンテキストとビルドファイルを受け取り、シリアライズされた LLB グラフを返します。
重要なのは「ビルド言語が BuildKit に埋め込まれているわけではない」という点です。プラグ可能なレイヤーとして設計されています。YAML スペック、TOML 設定、あるいは独自 DSL を読み取るフロントエンドを書けば、BuildKit は Dockerfile と同じように実行します。
この仕組みは以前から見たことがあるでしょう。Dockerfile の先頭に
# syntax= ディレクティブを置くと、BuildKit がどのフロントエンドイメージを使うか指定できます。# syntax=docker/dockerfile:1 はデフォルトです。任意のイメージを指すことも可能です。
ソルバーとキャッシュ:内容アドレス化された実行
ソルバーは LLB グラフを取り込み、実行します。DAG の各頂点は内容アドレス化されているため、同じ入力で既にビルドしたステップがあれば、その処理全体をスキップできます。これが BuildKit が高速なのです:旧式の Docker ビルダーのように層を線形にキャッシュするだけではなく、操作レベルでグラフ全体をキャッシュし、独立した枝を並列実行します。
キャッシュはローカル、インライン(イメージ内埋め込み)、またはリモート(レジストリ)にできます。これにより BuildKit のビルドは再現性が高く、CI ランナー間で共有可能です。
画像以外の用途
BuildKit の
--output フラグが実際の使い道を示します。結果を以下のようにエクスポートできます:
— レジストリへプッシュ(type=image
のデフォルト)docker build
— 最終ファイルシステムをローカルディレクトリへ出力type=local,dest=./out
— tarball としてエクスポートtype=tar,dest=./out.tar
— OCI イメージ tarball としてエクスポートtype=oci
type=local 出力は画像以外のケースで最も興味深いです。ビルドでコンパイル済みバイナリ、パッケージ、ドキュメントなどを生成し、BuildKit が結果をディスクにダンプします。コンテナイメージは不要です。
Earthly・Dagger・Depot などのプロジェクト
これらはすべて BuildKit の LLB をベースに構築されています。実績あるパターンです。
カスタムフロントエンドで APK パッケージをビルド
具体例として、apkbuild を作りました。これは YAML スペックを読み取り、Alpine APK パッケージを生成する BuildKit フロントエンドです(Dockerfile は不要)。ソースのコンパイルから APK へのパッケージングまで、すべて LLB 操作で BuildKit 内部で実行されます。Chainguard の melange のダミーバージョンと考えてください。
YAML を選んだのは馴染みがあるためですが、スキーマは JSON、TOML、独自 DSL でも構いません。フロントエンドがパースできれば何でも OK です。
パッケージ YAML スペック
name: hello version: "1.0.0" epoch: "0" url: https://example.com/hello license: MIT description: Minimal CMake APK demo sources: app: context: {} build: source_dir: hello
Dockerfile やシェルスクリプトは不要です。BuildKit はこのスペックをカスタムフロントエンド経由で読み取り、
.apk ファイルを生成します。
実行手順
-
フロントエンドイメージのビルド
docker build -t tuananh/apkbuild -f Dockerfile . -
APK パッケージのビルドに使用
cd example docker buildx build \ -f spec.yml \ --build-arg BUILDKIT_SYNTAX=tuananh/apkbuild \ --output type=local,dest=./out \ .
out フォルダーに APK パッケージが生成されているはずです。BUILDKIT_SYNTAX が BuildKit にデフォルトの Dockerfile パーサではなく、カスタムフロントエンドを使用するよう指示し、--output type=local が結果の .apk ファイルを ./out にダンプします。イメージは作成されず、レジストリも関与しません。
なぜ重要なのか
BuildKit は内容アドレス化・並列実行・キャッシュ機能を備えたビルドエンジンを無料で提供してくれます。キャッシングや並列処理、再現性を自前で作る必要はありません。自分のスペックを LLB に変換するフロントエンドを書けば、BuildKit が残りを担います。
これは単なるデモに留まらず、Dagger は CI/CD パイプラインの実行エンジンとして LLB を使用し、Earthly は Earthfile を LLB にコンパイルします。このパターンは大規模で検証済みです。
コードをコンパイルしたり、アーティファクトを生成したり、多段階ビルドを調整するツールを作る場合は、BuildKit を実行バックエンドとして検討してください。Dockerfile はあくまでデフォルトのフロントエンドに過ぎず、本当の力はその下にあるエンジンにあります。