Help us shape the future of Go! Take the 2026 Go Developer Survey

buildkit

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: MIT Imports: 51 Imported by: 0

Documentation

Overview

Package buildkit drives image builds via direct integration with the BuildKit Go client. The build graph is authored in LLB so each devcontainer feature install becomes its own cacheable vertex, and the VS Code server is fetched via llb.HTTP — the BuildKit content store caches it independently of the docker layer cache.

A Dockerfile equivalent of the same graph is still generated by pkg/dockerfile for inspection and for the `generate` subcommand, but it's not the source of truth at build time.

relationships:

references: [export, client]

relationships:

references: [dockerfile]

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Build

func Build(in GraphInputs) (llb.State, error)

Build returns the LLB state representing the final image filesystem.

Cache notes:

  • Each feature install is a distinct exec vertex keyed off the feature's directory contents and its option environment, so adding a new feature only invalidates downstream features (in install order) — it does not invalidate earlier ones.
  • The VS Code server tarball is sourced via llb.HTTP with the SHA256 digest as the cache key. As long as the digest is stable, the download vertex is cached even across full rebuilds.
  • The local context (feature directories) is registered as a single llb.Local with include patterns, so unrelated workspace files don't bust the build cache.

func DefaultAddress

func DefaultAddress() string

DefaultAddress returns the BuildKit address to dial when none is provided: the BUILDKIT_HOST environment variable, or empty, which selects the Docker daemon's built-in BuildKit.

Types

type BuildSpec

type BuildSpec struct {
	// Graph is the devcontainer LLB graph description. Its Platform
	// field is overridden per target platform when SolveOptions
	// requests more than one.
	Graph GraphInputs
	// Upstream, when non-nil, is built via the dockerfile.v0 frontend
	// and used as the base for Graph (Graph.BaseImage / BaseState are
	// ignored in that case).
	Upstream *DockerfileBuild
	// Labels are set on the image config, over any the base image
	// carries.
	Labels map[string]string
}

BuildSpec is the input to SolveDevcontainer. It bundles the LLB graph inputs together with an optional upstream Dockerfile that should be built first and chained as the base image.

type CacheRef

type CacheRef struct {
	Type  string
	Attrs map[string]string
}

CacheRef is a small mirror of client.CacheOptionsEntry that's easier for CLI flag parsing.

func ParseCacheRefs

func ParseCacheRefs(specs []string) []CacheRef

ParseCacheRefs parses cache specs in `docker build` form ("type=registry,ref=...") into CacheRefs. A spec with no "=" is a registry reference, as `docker buildx` treats it.

type Connection

type Connection struct {
	// BuildKit is the BuildKit control client.
	BuildKit *client.Client
	// Docker is the Engine API client. It is always set: it carries the
	// dial for the daemon's BuildKit, and image loads for a separate one.
	Docker *dockerclient.Client
	// Address is the BuildKit address dialed, or empty for the daemon's
	// built-in BuildKit.
	Address string
	// Daemon reports whether BuildKit is the Docker daemon's own.
	Daemon bool
	// contains filtered or unexported fields
}

Connection is a BuildKit client together with the Docker Engine API client used to reach the daemon.

When the connection dials the Docker daemon's built-in BuildKit (the default), Daemon is true: results are exported straight into the daemon's image store and image references resolve against local images first. When it dials a separate BuildKit (BUILDKIT_HOST or an explicit address), Daemon is false and loaded images are streamed to the Engine API image-load endpoint instead.

func Connect

func Connect(ctx context.Context, addr string, docker *dockerclient.Client) (*Connection, error)

Connect opens a BuildKit connection.

The address is taken from addr, then BUILDKIT_HOST. When both are empty, Connect dials the Docker daemon's built-in BuildKit through the Engine API (the "/grpc" and "/session" upgrade endpoints, as `docker buildx` does for its default "docker" driver), so stock Docker needs no extra setup.

docker is the Engine API client to use; when nil, one is created from the standard DOCKER_* environment and closed with the Connection.

func (*Connection) Close

func (c *Connection) Close() error

Close releases the BuildKit client and, when Connect created it, the Engine API client.

func (*Connection) Describe

func (c *Connection) Describe() string

Describe names the BuildKit endpoint for logs and errors.

type DockerfileBuild

type DockerfileBuild struct {
	// OmitSyntaxDirective removes syntax directives from the frontend input.
	OmitSyntaxDirective bool
	// ContextDir is the host directory exposed to the dockerfile
	// frontend as its build context.
	ContextDir string
	// DockerfileDir is the host directory containing the Dockerfile.
	// Empty means use ContextDir.
	DockerfileDir string
	// Filename is the Dockerfile name (default "Dockerfile").
	Filename string
	// Target selects a specific build stage.
	Target string
	// BuildArgs become "build-arg:KEY=VAL" frontend opts.
	BuildArgs map[string]string
	// Labels become "label:KEY=VAL" frontend opts.
	Labels map[string]string
}

DockerfileBuild describes a Dockerfile built through the builtin "dockerfile.v0" frontend: either the base of a devcontainer image (BuildSpec.Upstream), solved inside the same gateway build invocation as the rest of the LLB graph so no docker round-trip is required, or a standalone image (SolveDockerfile).

type GraphInputs

type GraphInputs struct {
	Spec     *spec.DevContainer
	Metadata metadata.CollectOptions
	// BaseImage names the FROM image. Ignored when BaseState is set.
	BaseImage string
	// BaseState, when non-nil, is used as the starting llb.State instead
	// of llb.Image(BaseImage). This is how we chain on top of a Dockerfile
	// frontend solve in the gateway path: the upstream solve produces a
	// Reference whose ToState() becomes the base for our overlays.
	BaseState    *llb.State
	Features     []features.Resolved
	VSCodeServer *vscode.Result
	// LocalContextName names the llb.Local mount that the resolved
	// feature directories will be exposed under (each feature lives at
	// _features/<SafeID>/ within that local context).
	LocalContextName string
	// FeaturesContextSubdir is the path within the local context where
	// the staged feature directories live.
	FeaturesContextSubdir string
	// RemoteUser overrides the spec's remoteUser (empty falls back to
	// the spec, then root).
	RemoteUser string
	// ImageUser is the user configured in the base image. Features see
	// it as the container user when the spec sets no containerUser.
	// Empty means root.
	ImageUser string
	// ResolveImageConfig, when true, performs a registry roundtrip at
	// LLB marshal time to inherit ENV/USER/WORKDIR from the base image.
	// Recommended; can be disabled for offline builds. Ignored when
	// BaseState is set (the upstream solve already resolved it).
	ResolveImageConfig bool
	// Platform constrains the LLB graph to the given target platform. A
	// zero-value Platform falls back to the daemon default. Authoring the
	// graph with an explicit Platform is required for cross-arch and
	// multi-platform builds — every llb.Image / llb.Run / llb.HTTP vertex
	// inherits the constraint.
	Platform dcplatform.Platform
}

GraphInputs collects every piece of information the LLB authoring routine needs.

type OutputSpec

type OutputSpec struct {
	Type        string
	Attrs       map[string]string
	Destination string
}

OutputSpec describes one buildx --output value. Attrs are exporter options; Destination is the client-side file or directory receiving the result.

func ParseOutput

func ParseOutput(raw string) (OutputSpec, error)

ParseOutput parses buildx CSV attributes and its short destination form. It has no filesystem side effects; the exporter opens its output on demand.

func (OutputSpec) Archive

func (o OutputSpec) Archive() bool

Archive reports whether the exporter writes an archive stream.

func (OutputSpec) Directory

func (o OutputSpec) Directory() bool

Directory reports whether the exporter writes a directory or OCI layout.

func (OutputSpec) ToStdout

func (o OutputSpec) ToStdout() bool

ToStdout reports whether archive bytes replace the normal stdout result.

type RegistryAuth

type RegistryAuth interface {
	// Credentials returns the credentials for a registry host.
	Credentials(host string) (registryauth.Credentials, error)
	// EngineAuth returns the Engine API X-Registry-Auth value for an
	// image reference, or "" for an anonymous request.
	EngineAuth(ref string) (string, error)
}

RegistryAuth supplies the registry credentials of a solve.

type Result

type Result struct {
	// SolveResponse is the raw BuildKit solve response.
	SolveResponse *client.SolveResponse
}

Result is returned from the Solve functions.

func Solve

func Solve(ctx context.Context, state llb.State, opt SolveOptions) (*Result, error)

Solve marshals the supplied state and submits it to BuildKit.

func SolveDevcontainer

func SolveDevcontainer(ctx context.Context, spec BuildSpec, opt SolveOptions) (*Result, error)

SolveDevcontainer drives a devcontainer build through the BuildKit gateway. Compared to Solve, it can:

  • Build for multiple target platforms in a single invocation, producing a manifest-list image.
  • Chain an upstream Dockerfile build directly (via the dockerfile.v0 frontend) so the base image never has to round-trip through the local docker store.

func SolveDockerfile

func SolveDockerfile(ctx context.Context, b DockerfileBuild, opt SolveOptions) (*Result, error)

SolveDockerfile builds a plain Dockerfile through the dockerfile.v0 frontend and exports the result as opt describes. All of opt.Platforms are built; more than one produces a manifest-list image.

type SolveOptions

type SolveOptions struct {
	// Address is the BuildKit endpoint. When empty, BUILDKIT_HOST is
	// consulted; when that is empty too, the Docker daemon's built-in
	// BuildKit is used through the Engine API.
	Address string
	// Docker is the Engine API client. When nil, one is created from the
	// standard DOCKER_* environment.
	Docker *dockerclient.Client
	// LocalContextName must match the name used in the LLB graph.
	LocalContextName string
	// LocalContextDir is the host directory exposed to the build under
	// LocalContextName.
	LocalContextDir string
	// Tags name the exported image.
	Tags []string
	// Push pushes the image to the registry named by Tags. With the
	// daemon's BuildKit the image is also kept in the daemon's image
	// store, from which the Engine API pushes it.
	Push bool
	// Load puts the image into the Docker daemon's image store. With the
	// daemon's BuildKit the image is exported there directly; with a
	// separate BuildKit it is streamed to the Engine API image-load
	// endpoint.
	Load bool
	// LoadWriter, when set with Load, receives a docker-format image
	// tarball. With a separate BuildKit the image is not loaded into the
	// daemon; with the daemon's BuildKit it is also kept in the daemon's
	// image store, from which the Engine API saves it.
	LoadWriter io.Writer
	// Output is a buildx exporter specification or a local destination path.
	Output string
	// OutputWriter receives archive output when dest is "-" or omitted.
	OutputWriter io.Writer
	// OutputDir, when non-empty, requests a "local" exporter writing
	// the image filesystem to this directory.
	OutputDir string
	// CacheImports / CacheExports map directly to BuildKit's options.
	CacheImports []CacheRef
	CacheExports []CacheRef
	// Platforms is the list of target platforms. SolveDevcontainer and
	// SolveDockerfile honor all entries (producing a manifest-list image
	// for >1); the bare Solve uses none.
	Platforms []string
	// NoCache disables the build cache for every step.
	NoCache bool
	// Pull always fetches referenced images from their registry. When
	// false, the daemon's BuildKit prefers images already in the local
	// image store.
	Pull bool
	// FrontendAttrs are passed through verbatim. Useful for advanced
	// callers; normally empty.
	FrontendAttrs map[string]string
	// RegistryAuth supplies registry credentials. BuildKit asks for them
	// through the client session to pull and push, and a push from the
	// daemon's image store sends them to the Engine API. When nil, the
	// docker CLI's configuration is read (registryauth.FromEnvironment).
	RegistryAuth RegistryAuth
	// Progress controls the display: "auto", "tty", "plain".
	Progress string
	// Stdout / Stderr default to os.Stdout / os.Stderr.
	Stdout io.Writer
	Stderr io.Writer
}

SolveOptions describes which BuildKit to use and how to export the resulting image.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL