BuildKit Documentation

repository·master·Indexed 27 days ago

https://github.com/moby/buildkit

An extensible, high-performance build engine for converting source code into container images and other build artifacts. BuildKit features concurrent dependency resolution, efficient caching, and multiple output formats. It serves as the underlying engine for tools like Docker buildx, Tekton Pipelines, Dagger, and Earthly. The toolkit consists of the buildkitd daemon and the buildctl client, supporting advanced capabilities such as SBOM and SLSA provenance attestations, LLB (Low-Level Build definition), and rootless execution.

Tokens
63.1K
Snippets
190
Records
366
Agent score
93%

What's inside BuildKit

  1. Overview of BuildKit

    master

    BuildKit is a toolkit designed to convert source code into build artifacts efficiently, expressively, and repeatably. It is a standalone, full-featured build engine that can be used directly or via integrations.

    Key Features:

    • Automatic garbage collection
    • Extendable frontend formats
    • Concurrent dependency resolution
    • Efficient instruction caching
    • Build cache import/export
    • Nested build job invocations
    • Distributable workers
    • Multiple output formats
    • Pluggable architecture
    • Execution without root privileges

    Note on Docker Usage: If you only need BuildKit-specific Dockerfile features (like RUN --mount=type=...), you likely do not need to use BuildKit standalone. Since Docker Engine 23.0, docker build uses Buildx and BuildKit by default.

  2. Understand BuildKit project scope and purpose

    master

    BuildKit is a specialized tool for build graph execution and caching.

    What BuildKit IS:

    • A solution for defining, executing, and caching build graphs efficiently.
    • A platform for containerized build tooling using containers as execution sandboxes.
    • A flexible API for various tools and use cases.
    • A tool where buildctl is designed to expose API features as directly as possible.

    What BuildKit IS NOT:

    • A tool for running processes on the host.
    • A manager for deploying or combining multiple BuildKit instances.
    • A provider of opinionated client-side UX (except for buildctl debug).
    • A replacement for external projects that manage build requests or invent new frontends.

    Recommendation: If you are an end user, consider using a tool built with BuildKit (like Docker) rather than using BuildKit directly.

  3. Understand BuildKit SLSA Provenance support

    master

    BuildKit supports the creation of SLSA (Supply-chain Levels for Software Artifacts) Provenance for builds it executes. It generates provenance in formats compliant with both SLSA v0.2 and SLSA v1 specifications.

    When generating attestations, the level of detail included in the provenance depends on the selected mode:

    • mode=min: Includes a minimal set of required fields.
    • mode=max: Includes an expanded set of fields providing more granular build metadata.
  4. Understand the BuildKit Solver Design

    master

    The BuildKit solver is the component responsible for parsing build definitions and scheduling operations to workers. It is optimized for:

    • Deduplication: Identical operations (based on content-addressable digests) are executed once and shared across concurrent requests.
    • Caching: Supports remote and local caching with different per-vertex modes (selector-based vs. content-based).
    • Concurrency: Efficiently handles multiple simultaneous build requests by sharing a graph of vertices.

    Key concept: The solver uses a content-addressable graph where each vertex has a unique Digest(). If two vertices have the same digest, they are considered identical, and concurrent requests for that vertex will wait for the same single operation to complete.

  5. Understand the BuildKit Scheduler

    master

    The scheduler is a single-threaded, non-blocking event loop responsible for invoking operations to solve the build graph. It operates by solving edges rather than vertices.

    Key concepts:

    • Pipes: Interaction with the scheduler occurs via "pipes" between a sender and a receiver. One or both sides can be an edge instance.
    • Unparking: When an edge receives an event via a pipe, the scheduler "unparks" it. The unpark handler must be non-blocking and execute quickly.
    • Requests: The scheduler separates pipes into incoming requests (e.g., requests to retrieve a result or cache key) and outgoing requests (e.g., requests for async functions or requesting an input edge to reach a specific state).

    Critical Rule for Implementation: To prevent deadlocks and panics, the unpark method must ensure that if it finishes without completing all incoming requests, it must have created outgoing requests. Conversely, if an incoming request remains pending, at least one outgoing request must exist.

  6. Understand the BuildKit Solve Request Lifecycle

    master

    BuildKit solves build graphs to find the final result. A solve request can be either definition-based (providing an LLB definition directly) or frontend-based (providing a frontend name).

    When a request is made:

    1. The client sends a solve request to buildkitd via gRPC.
    2. The controller passes it to the LLB solver, which creates a Job and a FrontendLLBBridge.
    3. Definition-based solves: The solver builds the provided LLB definition directly.
    4. Frontend-based solves: The solver runs the specified frontend (e.g., dockerfile.v0 or gateway.v0) via the bridge. Frontends can issue their own solve requests back to the bridge, allowing for composable frontends. If a frontend makes a frontend-based solve request, it shares the same FrontendLLBBridge and underlying Job.
    5. Results are returned to the client, and the temporary job and bridge are discarded.
  7. Requirements for Experimental Windows Container Support

    master

    BuildKit provides experimental support for Windows containers (WCOW) as of v0.13.

    Architecture: amd64 (primary), arm64 (available but not officially tested). Supported OS: Windows Server 2019, Windows Server 2022, and Windows 11. Supported Base Images: ServerCore:ltsc2019, ServerCore:ltsc2022, and NanoServer:ltsc2022. Dependency: Requires containerd v1.7.7 or higher.

  8. Understand BuildKit core terminology

    master

    BuildKit uses a specific set of terms to describe its architecture and build processes. Familiarize yourself with these concepts before contributing or integrating:

    • LLB (Low-Level Build definition): A binary intermediate format used to define the dependency graph for build processes.
    • Definition: The LLB serialized using protocol buffers, used for transport over gRPC interfaces.
    • Frontend: Components that build LLB and issue requests to BuildKit's gRPC server (e.g., dockerfile.v0, gateway.v0).
    • State: A helper object used by frontends to build LLBs from high-level concepts like images, shell executions, or mounts.
    • Solver: An abstract interface that solves a graph of vertices and edges to find a final result.
    • Vertex: A node in a build graph defining a content-addressable operation and its inputs.
    • Op (Operation): Defines how a solver evaluates a vertex; executed in the worker (e.g., image sources, git sources, exec processes).
    • Edge: A connection point between vertices that references a specific output from a vertex's operation.
    • Result: The abstract interface return value of a solve, typically representing a container snapshot.
    • Worker: A backend that runs OCI images (e.g., using runc or containerd).
  9. Use ARG instructions to define build-time variables

    master

    The ARG instruction defines variables that can be passed to the builder at build time using the --build-arg <varname>=<value> flag. These variables can be used in instructions like FROM, ENV, WORKDIR, and RUN using ${VAR} or $VAR syntax.

    Key Characteristics:

    • Scope: An ARG variable is available from the line it is declared onwards. In multi-stage builds, an ARG declared in one stage is not automatically available in others unless redefined or inherited from a shared base stage.
    • Persistence: Unlike ENV, ARG variables are not embedded in the final image and are not available in the running container.
    • Security Warning: Do not use ARG for secrets (credentials, API tokens). They are visible in docker history and provenance attestations. Use RUN --mount=type=secret for secure secret handling.
    ARG <name>[=<default value>] [<name>[=<default value>]...]
    
    # Example with default values
    FROM busybox
    ARG user1=someuser
    ARG buildno=1
  10. Set up BuildKit on Windows

    master

    To install BuildKit on Windows, you must run a PowerShell terminal as an Administrator.

    1. Enable Windows Features: Enable Containers and Microsoft-Hyper-V.
    2. Install containerd: Follow the official containerd installation guide for Windows. BuildKit currently only supports the containerd worker.
    3. Configure CNI: Set up CNI networking (see CNI/Networking Setup section).
    4. Download and Extract BuildKit: Download the latest release binaries and extract them.
    5. Install Binaries: Move buildkitd.exe and buildctl.exe to a permanent directory (e.g., $Env:ProgramFiles\buildkit) and add that directory to your system PATH.
    # 1. Enable Windows Features
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V, Containers -All
    
    # 4. Download and extract
    $url = "https://api.github.com/repos/moby/buildkit/releases/latest"
    $version = (Invoke-RestMethod -Uri $url -UseBasicParsing).tag_name
    $arch = "amd64"
    curl.exe -fSLO https://github.com/moby/buildkit/releases/download/$version/buildkit-$version.windows-$arch.tar.gz
    mv bin bin2
    tar.exe xvf .\buildkit-$version.windows-$arch.tar.gz
    
    # 5. Setup binaries and PATH
    Copy-Item -Path ".\\bin" -Destination "$Env:ProgramFiles\\buildkit" -Recurse -Force
    $Path = [Environment]::GetEnvironmentVariable("PATH", "Machine") + `
        [IO.Path]::PathSeparator + "$Env:ProgramFiles\\buildkit"
    [Environment]::SetEnvironmentVariable( "Path", $Path, "Machine")
    $Env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + `
        [System.Environment]::GetEnvironmentVariable("Path","User")