build

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Overview

Package build turns a validated git checkout into a tagged Docker image through rootless BuildKit (docs/BUILD_PLAN.md E1.2, docs/DECISIONS.md D-018).

The control plane never runs a build itself: it sends the checkout to a `buildkitd` running as a compose service on the private network and streams the resulting image tarball into the Docker Engine through the socket-proxy. Build secrets are exposed to `RUN` steps solely as BuildKit secret mounts (`--mount=type=secret,id=NAME`), which live in a tmpfs for the duration of the step and never enter an image layer, the image config, or the build log (golden rule 3). Passing a secret as a build argument is rejected before the build starts.

Index

Constants

View Source
const AutoDockerfileName = ".redoubt.Dockerfile"

AutoDockerfileName is the file WriteAutoDockerfile creates inside the checkout.

View Source
const DefaultDockerfile = "Dockerfile"

DefaultDockerfile is the Dockerfile path used when Request.Dockerfile is empty.

View Source
const DefaultTimeout = 20 * time.Minute

DefaultTimeout bounds one build (solve + load into Docker) when BuildKit.Timeout is zero.

Variables

View Source
var ErrAutoDockerfileExists = errors.New("build: auto-Dockerfile target already exists")

ErrAutoDockerfileExists is returned when the checkout already contains an entry named AutoDockerfileName (file, directory, or symlink). It is never overwritten or followed.

View Source
var ErrInvalidRequest = errors.New("build: invalid request")

ErrInvalidRequest wraps every validation failure of a Request.

View Source
var ErrNoBuilder = errors.New("build: builder is not configured")

ErrNoBuilder is returned when the BuildKit builder has no address or Docker client.

View Source
var ErrNoRuntime = errors.New("build: no Dockerfile and no recognised runtime (node, python, go, static)")

ErrNoRuntime is returned when a directory has no Dockerfile and matches no curated runtime.

View Source
var ErrNoWorkers = errors.New("build: buildkitd reports no workers")

ErrNoWorkers is returned by Ping when buildkitd is reachable but reports no workers.

Functions

This section is empty.

Types

type BuildKit

type BuildKit struct {
	// Addr is the buildkitd endpoint: tcp://host:port or unix:///path.
	Addr string
	// Docker receives the built image (LoadImage) and confirms it (ImageExists).
	Docker *docker.Client
	// Timeout bounds one Build call; zero means DefaultTimeout.
	Timeout time.Duration
	// KeepDuration, when non-zero, protects cache records younger than this from Prune.
	KeepDuration time.Duration
	// Logger receives non-secret progress and prune summaries; nil uses slog.Default.
	Logger *slog.Logger
}

BuildKit builds images through a remote rootless buildkitd (D-018) and loads them into the Docker Engine via the platform's Docker client (which talks to the socket-proxy).

func New

func New(addr string, d *docker.Client) *BuildKit

New returns a BuildKit builder for the given buildkitd address.

func (*BuildKit) Build

func (b *BuildKit) Build(ctx context.Context, req Request) (Result, error)

Build validates req, solves the Dockerfile on buildkitd with the docker exporter streaming straight into Docker's image load, then confirms the image is present.

func (*BuildKit) DiskUsage

func (b *BuildKit) DiskUsage(ctx context.Context) (int64, error)

DiskUsage returns the total size in bytes of buildkitd's cache records.

func (*BuildKit) Ping

func (b *BuildKit) Ping(ctx context.Context) error

Ping checks that buildkitd is reachable and has at least one worker.

func (*BuildKit) Prune

func (b *BuildKit) Prune(ctx context.Context, keepBytes int64) error

Prune asks buildkitd to release cache until at most keepBytes remain, keeping records younger than KeepDuration when it is set. Pruned records are summarised (count and bytes) via slog.

type Builder

type Builder interface {
	Build(ctx context.Context, req Request) (Result, error)
}

Builder builds images. BuildKit is the production implementation; Fake is for tests.

type Fake

type Fake struct {

	// Calls holds every request passed to Build, in order.
	Calls []Request
	// Err, when set, is returned by Build after recording the request.
	Err error
	// ImageID is reported in every Result ("sha256:fake" when empty).
	ImageID string
	// Duration is reported in every Result.
	Duration time.Duration
	// Validate, when true, makes Build return Request.Validate errors like the real builder.
	Validate bool
	// contains filtered or unexported fields
}

Fake is a Builder for other packages' tests. It validates and records every request and returns a Result for the requested ImageRef (or Err). Safe for concurrent use.

func (*Fake) Build

func (f *Fake) Build(ctx context.Context, req Request) (Result, error)

Build records req and returns a Result (or Err). When f.Validate is set the request is validated first so callers' tests catch traversal and secret-as-arg mistakes too.

func (*Fake) Requests

func (f *Fake) Requests() []Request

Requests returns a copy of the recorded requests.

type Request

type Request struct {
	// DeploymentID and App identify the build in logs and errors.
	DeploymentID string
	App          string
	// ContextDir is the absolute, clean path of the build context (a checkout under workspace/
	// already validated by the git package).
	ContextDir string
	// Dockerfile is the Dockerfile path relative to ContextDir ("Dockerfile" when empty). It must
	// stay inside ContextDir.
	Dockerfile string
	// ImageRef is the tag the built image is loaded under: redoubt/<app>:<deploy-id>.
	ImageRef string
	// Secrets maps secret id to value. Each is exposed ONLY as --mount=type=secret,id=<id>;
	// never as a build argument, never in the image, never in Logs.
	Secrets map[string]string
	// BuildArgs are non-secret Dockerfile ARG values. A key or value that is also a secret is
	// rejected by Validate.
	BuildArgs map[string]string
	// Logs receives the BuildKit progress stream, one line per event prefixed by the step name.
	// The caller wraps it in the secrets redactor; nil discards the stream.
	Logs io.Writer
	// Platform optionally selects the target platform (e.g. "linux/amd64"); empty uses the
	// builder's native platform.
	Platform string
}

Request describes one image build.

func (Request) Validate

func (r Request) Validate() error

Validate checks the request without touching BuildKit. It returns every problem joined into one ErrInvalidRequest. Errors name secrets and build args by key only, never by value.

type Result

type Result struct {
	// ImageRef is the tag the image was loaded under (== Request.ImageRef).
	ImageRef string
	// ImageID is the image config digest, the id Docker reports for the loaded image.
	ImageID string
	// Duration is the wall-clock time of the build including the load into Docker.
	Duration time.Duration
}

Result is a completed build.

type Runtime

type Runtime string

Runtime is a curated auto-Dockerfile family (build plan §2: Node, Python, Go, static).

const (
	RuntimeNode   Runtime = "node"
	RuntimePython Runtime = "python"
	RuntimeGo     Runtime = "go"
	RuntimeStatic Runtime = "static"
)

Detected runtimes.

func Detect

func Detect(dir string) (Runtime, string, error)

Detect inspects dir. When it contains a Dockerfile it returns ("", "", nil): the app's own Dockerfile wins and nothing is generated. Otherwise it returns the runtime and the curated Dockerfile content, or ErrNoRuntime. Detection order: node, go, python, static.

func WriteAutoDockerfile

func WriteAutoDockerfile(dir string) (string, Runtime, error)

WriteAutoDockerfile writes the curated Dockerfile for dir as <dir>/.redoubt.Dockerfile and returns its path (relative to dir, ready for Request.Dockerfile) and runtime. When dir already has a Dockerfile it returns ("Dockerfile", "", nil) without writing anything.

Jump to

Keyboard shortcuts

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