Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fussybeaver/bollard/llms.txt

Use this file to discover all available pages before exploring further.

Bollard provides a first-class BuildKit integration via a gRPC layer that communicates directly with BuildKit’s control API. Unlike the classic /build HTTP endpoint, the BuildKit path supports advanced features: multi-platform builds, cache import/export, SSH forwarding, secret mounts, named contexts, and OCI/Docker image export.
The BuildKit API requires the buildkit or buildkit_providerless Cargo feature flag plus either the chrono or time feature for OAuth authentication token handling.
# Cargo.toml
[dependencies]
bollard = { version = "*", features = ["buildkit_providerless", "time"] }

ImageBuildFrontendOptionsBuilder

The primary builder for configuring a BuildKit solve request. Construct it via ImageBuildFrontendOptions::builder() or ImageBuildFrontendOptionsBuilder::new(), call the desired setters, then finalise with .build().
use bollard::grpc::build::ImageBuildFrontendOptions;

let opts = ImageBuildFrontendOptions::builder()
    .dockerfile(std::path::Path::new("Dockerfile"))
    .target("release")
    .nocache(false)
    .pull(true)
    .buildarg("APP_VERSION", "1.0.0")
    .label("org.opencontainers.image.source", "https://github.com/example/repo")
    .build();

Builder methods

MethodSignatureDescription
dockerfile(path: &Path) -> SelfPath within the build context to the Dockerfile. Defaults to Dockerfile at the root.
target(target: &str) -> SelfNamed build stage to stop at (multi-stage builds).
nocache(nocache: bool) -> SelfDisable layer caching entirely.
pull(pull: bool) -> SelfAttempt to pull the base image even if a local copy exists.
buildarg(key: &str, value: &str) -> SelfInject a --build-arg. May be called multiple times.
label(key: &str, value: &str) -> SelfAttach an image label. May be called multiple times.
platforms(value: &ImageBuildPlatform) -> SelfAdd a target platform (OS + architecture + optional variant). May be called multiple times for multi-platform builds.
force_network_mode(value: &ImageBuildNetworkMode) -> SelfOverride the network mode for RUN steps.
extrahost(value: &ImageBuildHostIp) -> SelfAdd an extra entry to /etc/hosts during the build.
shmsize(value: u64) -> SelfSize of /dev/shm in bytes (default 64 MiB).
set_secret(key: &str, source: &SecretSource) -> SelfBind a build-time secret without persisting it into the image. See Secret mounts.
enable_ssh(value: bool) -> SelfForward the host SSH agent into the build. Requires SSH_AUTH_SOCK to be set.
named_context(key: &str, value: NamedContext) -> SelfOverride a named build context (e.g. another image or a Git URL).
cacheto(value: &CacheOptionsEntry) -> SelfExport build cache to a registry or local path.
cachefrom(value: &CacheOptionsEntry) -> SelfImport build cache from a registry or local path.
build() -> ImageBuildFrontendOptionsConsume the builder and return the finalised options.

Driver types

The driver determines how Bollard connects to BuildKit. Choose based on your environment.

MobyDriver

Builds via the Docker daemon’s built-in BuildKit (DOCKER_BUILDKIT=1). Uses the /session and /grpc HTTP upgrade endpoints over the existing Docker socket connection — no extra process required.
use bollard::grpc::driver::moby::Moby;
use bollard::grpc::driver::Build;

// docker is a bollard::Docker instance
let moby = Moby::new(&docker);
moby.docker_build("myimage:latest", opts, load_input, None, None).await?;
This is the simplest driver and works with any Docker installation that has BuildKit enabled (Docker 18.09+).

DockerContainerDriver

Spawns a dedicated BuildKit container (moby/buildkit) inside Docker and communicates via exec stdin/stdout. Useful when you need a pinned BuildKit version or features not yet in the daemon’s built-in builder.
use bollard::grpc::driver::docker_container::DockerContainer;

BuildkitdDriver

Connects directly to a standalone buildkitd daemon over a TCP socket. Ideal for CI environments where buildkitd runs as a sidecar or system service.
use bollard::grpc::driver::buildkitd::BuildkitDaemon;

Export types — ImageExporterEnum

After a successful build, you can export the resulting image to different targets:
VariantDescription
ImageExporterEnum::OCI(ImageExporterRequest)Write the image as an OCI image tarball (type=oci).
ImageExporterEnum::Docker(ImageExporterRequest)Write the image as a Docker image tarball (type=docker).
Construct an ImageExporterRequest using ImageExporterOutput::builder:
use bollard::grpc::export::ImageExporterOutput;
use bollard::grpc::driver::ImageExporterEnum;
use std::path::Path;

let exporter_request = ImageExporterOutput::builder("docker.io/library/my-image:latest")
    .dest(Path::new("/tmp/my-image.tar"));

let exporter = ImageExporterEnum::OCI(exporter_request);

ImageExporterOutputBuilder methods

MethodDescription
compression(&ImageBuildOutputCompression)Compression algorithm: Uncompressed, Gzip (default), Estargz, or Zstd.
compression_level(u8)Compression level (algorithm-specific).
force_compression(bool)Force re-compression even if already compressed.
oci_mediatypes(bool)Use OCI media types in manifests (default: true for OCI, false for Docker).
annotation(key: &str, value: &str)Attach an OCI annotation to the exported manifest.
dest(path: &Path) -> ImageExporterRequestFinalise and set the output file path.

ImageBuildLoadInput

The build context is passed as a compressed tar archive wrapped in ImageBuildLoadInput.
#[non_exhaustive]
pub enum ImageBuildLoadInput {
    Upload(Bytes),
}
VariantDescription
Upload(Bytes)A gzip-compressed tar archive containing the build context (Dockerfile and supporting files).

Creating a build context

use std::io::Write;
use bollard::grpc::build::{ImageBuildFrontendOptions, ImageBuildLoadInput};

let dockerfile = r#"
FROM alpine AS builder
RUN echo "hello" > /hello.txt
FROM alpine
COPY --from=builder /hello.txt /hello.txt
ENTRYPOINT ["cat", "/hello.txt"]
"#;

// Pack the Dockerfile into a tar archive
let mut header = tar::Header::new_gnu();
header.set_path("Dockerfile").unwrap();
header.set_size(dockerfile.len() as u64);
header.set_mode(0o644);
header.set_cksum();

let mut tar_builder = tar::Builder::new(Vec::new());
tar_builder.append(&header, dockerfile.as_bytes()).unwrap();
let uncompressed = tar_builder.into_inner().unwrap();

// Gzip-compress it
let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
encoder.write_all(&uncompressed).unwrap();
let compressed = encoder.finish().unwrap();

let load_input = ImageBuildLoadInput::Upload(bytes::Bytes::from(compressed));

Secret mounts

Secrets are passed to the build via set_secret on the builder. They are available inside RUN steps via --mount=type=secret and are never persisted in the final image layers.
use bollard::grpc::build::{ImageBuildFrontendOptions, SecretSource};

let opts = ImageBuildFrontendOptions::builder()
    // Source a secret from a file on the host
    .set_secret("aws-creds", &SecretSource::File("/home/user/.aws/credentials".into()))
    // Source a secret from an environment variable
    .set_secret("api-key", &SecretSource::Env("MY_API_KEY".to_string()))
    .build();
Corresponding Dockerfile instructions:
RUN --mount=type=secret,id=aws-creds,target=/root/.aws/credentials \
    aws s3 sync s3://my-bucket /app/assets

RUN --mount=type=secret,id=api-key,env=MY_API_KEY \
    curl -H "Authorization: Bearer $MY_API_KEY" https://api.example.com/data

SSH forwarding

Enable SSH agent forwarding with .enable_ssh(true). The host SSH_AUTH_SOCK environment variable must be set.
let opts = ImageBuildFrontendOptions::builder()
    .enable_ssh(true)
    .build();
RUN --mount=type=ssh git clone git@github.com:private/repo.git

Complete example — build and export

use bollard::Docker;
use bollard::grpc::build::{ImageBuildFrontendOptions, ImageBuildLoadInput};
use bollard::grpc::driver::moby::Moby;
use bollard::grpc::driver::{Build, ImageExporterEnum};
use bollard::grpc::export::ImageExporterOutput;
use std::io::Write;
use std::path::Path;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let docker = Docker::connect_with_socket_defaults()?;

    let dockerfile = "FROM alpine\nRUN echo hello\n";
    let mut header = tar::Header::new_gnu();
    header.set_path("Dockerfile").unwrap();
    header.set_size(dockerfile.len() as u64);
    header.set_mode(0o644);
    header.set_cksum();
    let mut tar_builder = tar::Builder::new(Vec::new());
    tar_builder.append(&header, dockerfile.as_bytes()).unwrap();
    let uncompressed = tar_builder.into_inner().unwrap();
    let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
    encoder.write_all(&uncompressed).unwrap();
    let compressed = encoder.finish().unwrap();

    let opts = ImageBuildFrontendOptions::builder()
        .pull(true)
        .build();

    let load_input = ImageBuildLoadInput::Upload(bytes::Bytes::from(compressed));

    let moby = Moby::new(&docker);
    moby.docker_build("my-app:latest", opts, load_input, None, None).await?;

    println!("Build complete");
    Ok(())
}
BuildKit requires Docker 18.09+ with BuildKit enabled (DOCKER_BUILDKIT=1) or a standalone buildkitd instance. The MobyDriver will return an error if the daemon does not support the /grpc endpoint upgrade.

Build docs developers (and LLMs) love