Skip to content
Documentation

Docs / Adapter commands / Docker

Docker adapter

Run Docker Buildx, Bake, or Compose with managed BuildKit cache. Keep the same build commands while reusable layers and selected build work move between machines.

Command
boringcache docker
Protocol
BuildKit type=boringcache backend
Action
mode: docker

How the adapter works

Shared layers by default

The managed type=boringcache backend carries BuildKit's cache graph and immutable layer bodies between CI runners and local builds.

Fresh execution when you need it

Opt-in --mount-cache persists RUN cache mounts independently of layer hits. Keep --no-cache or cache:false semantics while dependency and package-manager work remains reusable.

Native tool cache inside Docker

Opt-in tool cache composes sccache, ccache, Go, Bazel, Gradle, Maven, Nx, or Turbo with—or without—layer hits. Cargo uses mount cache for target and registry state plus sccache for compiler results.

Share mounts across separate image graphs

One tag addresses the layer cache. Add --mount-namespace so two jobs that need their own image graphs can still share cache mounts: give each job its own tag and both the same namespace. A bare value covers every mount; MOUNT_ID=NAMESPACE addresses one --mount=type=cache id, so a shared registry can sit beside separate target directories. Mounts you do not name keep the tag's identity. Requires --mount-cache. Set it in .boringcache.toml as adapters.docker.mount-namespace.

Two jobs can publish one namespace

A namespaced mount is shared on purpose, so publication combines rather than replaces. Before publishing, the job checks whether another job has published since its own restore; if so it merges the published files it does not already have, keeping its own copy of every shared path, and commits against the snapshot it merged. A job that loses that race merges again and retries instead of dropping its work. Deleted files are not propagated between jobs, so a namespace grows until its entry expires.

Configure BuildKit with TOML

Place buildkitd.toml in the directory where you run the command or an ancestor within the repository. BoringCache uses the nearest file, stopping at the Git root. Outside Git it stops at the .boringcache.toml directory, or the invocation directory when no repo config exists. Without a file, the worker uses its defaults.

Select another config file

Use --buildkitd-config path/to/buildkitd.toml before --, or set buildkitd-config under [adapters.docker] in .boringcache.toml. The CLI flag wins over the repo setting and discovery. CLI paths are relative to the invocation directory; repo paths are relative to .boringcache.toml. A selected missing, unreadable, or invalid file fails the build. Config files must be regular files no larger than 1 MiB.

Apply native worker settings

Use native BuildKit settings such as [worker.oci] max-parallelism = 1, registry mirrors, DNS, worker labels, and garbage-collection policies. Explicit TOML snapshotter and gc values take precedence over BoringCache defaults, including the snapshotter environment setting. Changed settings recreate the worker before the next build. max-parallelism limits concurrent build steps; BORINGCACHE_MANAGED_BUILDKIT_CPUS limits the worker container CPU quota and BORINGCACHE_MANAGED_BUILDKIT_CPUSET_CPUS selects host CPU IDs.

Keep file paths and connections explicit

Registry CA and client keypair files are read relative to the selected TOML file and copied privately into the worker. Certificate changes also recreate it. Other paths refer to files inside the worker container. BoringCache manages /var/lib/buildkit, the OCI worker, and the local Docker connection; incompatible root, grpc.address, grpc.tls, or worker-enable settings fail clearly. Use the native TOML format without changing these managed settings.

Set up Docker

Run boringcache onboard once, then use the Docker adapter from .boringcache.toml or wrap an explicit docker buildx build command. BuildKit still decides the cache graph; BoringCache gives it a first-class cache backend with shared storage, proxy uploads, and run diagnostics.

workspace = "my-org/my-project"

[adapters.docker]
tag = "image-main"
command = ["docker", "buildx", "build", "."]
tool-cache = ["sccache"]
mount-cache = true

[adapters.sccache]
tag = "rust-main"

Before the first run

  • Install Docker with Buildx available.
  • Run boringcache onboard once and commit .boringcache.toml.
  • Keep ordinary BuildKit layer reuse on unless the workload deliberately needs fresh instruction execution.

Use the same adapter in GitHub Actions

Docker mode runs the command committed under [adapters.docker], restores reusable layers, and lets trusted jobs publish new cache.

.github/workflows/ci.yml
- uses: boringcache/one@f0fb9b2d926a32b10c543e92093ba00c5a291b79 # v1.33.0
  with:
    trust-policy: auto
    mode: docker

Approve the repository through Connect CI and grant the job contents: read and id-token: write. The Action uses that Machine connection. Pull requests restore by default; trusted jobs may publish. See the authentication example in the GitHub Actions reference for scoped credentials when OIDC is unavailable.

GitHub Actions reference

Benchmarks

Mastodon shows fresh Docker execution: every Docker instruction reran while compiler and dependency work stayed warm. Immich shows why that matters after layer invalidation: BoringCache layers matched GHCR, while compiler and package-manager cache cut all 12 rebuilds.

2.9×

Faster Docker builds without layer hits

Across three Mastodon source changes on AMD64 and ARM64, ccache and persistent mounts averaged 2m 39s, compared with 7m 34s for cache:false.

Open run →

11–60%

Faster Docker builds

BoringCache cut measured build time by 11–60% across 6 public Docker comparisons with actions/cache.

Open run →

36%

Faster across every rebuild

Across three independently seeded trials, BoringCache + ccache + mount cache rebuilt Immich base images in 74m 23s, compared with 115m 47s for its GHCR registry cache.

Open run →

14%

Faster before warm reuse

BoringCache + ccache + mount cache built the Discourse ARM64 image graph in 20m 06s, compared with 21m 56s for BoringCache layers and 23m 26s for actions/cache.

Open run →

47

Pinned Docker workloads

The public catalog includes Go build cache, sccache, and Rust target cache mounts inside Docker builds.

Open run →

Tool reference

Check the tool's own reference when you need cache-key rules, build settings, or version-specific behavior.

All adapter commands

Compare every supported command, protocol, and Action mode in one place.

Adapter command index →

Need help or found something unclear? Open an issue or browse the CLI repo.