How to Build OCI Images Using `container build` with BuildKit

You can build OCI-compliant container images on macOS by using container build, which orchestrates a BuildKit-powered builder VM to execute Dockerfiles and produce multi-architecture outputs.

Apple's container CLI provides native OCI container support for Apple Silicon, leveraging the same high-performance BuildKit engine used by Docker. When you invoke container build, the CLI communicates with the container-builder-shim image to launch a lightweight Linux VM, mount your build context, and execute the Dockerfile instructions. The result is a fully OCI-compliant image stored locally or exported to a tarball.

Architecture Overview

The container build workflow relies on three core components working together to transform Dockerfiles into runnable images.

The container build Command

As documented in docs/command-reference.md, the container build command parses CLI flags, prepares the local build context, and forwards the request to the builder container. It supports standard Dockerfile instructions alongside Apple-specific extensions for multi-architecture output and custom export formats.

Builder VM and Shim

The builder runs inside a lightweight Linux VM launched by container builder start. This VM executes the container-builder-shim image (default ghcr.io/apple/container-builder-shim/builder:<tag>), which contains the BuildKit daemon. Resource limits for this VM—including CPU count, memory allocation, and Rosetta usage—are configurable via the [build] section of ~/.config/container/config.toml, as detailed in docs/container-system-config.md.

BuildKit Integration

BuildKit provides the underlying execution engine, enabling parallel step processing, intelligent cache sharing, and multi-platform output. According to docs/command-reference.md, you can target specific architectures using the --arch, --os, and --platform flags to produce images for multiple architectures (e.g., arm64 and amd64) in a single build invocation.

Starting the Builder

Before building images, you must start the builder VM with sufficient resources for your workload.


# Start with default resources (2 CPU / 2 GiB)

container builder start

# Or allocate specific resources for large builds

container builder start --cpus 8 --memory 32g

The builder persists across builds, maintaining the BuildKit cache for faster incremental builds. To apply configuration changes or free system resources, stop the builder:

container builder stop

Configuring Builder Resources

Persistent builder settings reside in ~/.config/container/config.toml. The [build] section controls the VM resources and the builder image version.

[build]
cpus = 8
memory = "16g"
rosetta = false          # Disable Rosetta for native-arm builds

image = "ghcr.io/apple/container-builder-shim/builder:0.12.0"

After modifying this file, restart the builder to apply changes:

container builder stop
container builder start

These configuration options are documented in docs/container-system-config.md and docs/how-to.md.

Building OCI Images

Basic Build Workflow

Create a Dockerfile (or Containerfile) in your project directory, then run:

container build --tag myorg/app:latest .

The CLI automatically pulls the builder shim if absent, launches the VM, and streams build progress to your terminal. The resulting image is stored in the local OCI-compliant image store.

Multi-Architecture Builds

Produce images for multiple architectures simultaneously using the --arch flag:

container build \
  --tag myorg/web-app:latest \
  --arch arm64 \
  --arch amd64 \
  --file Dockerfile \
  .

This leverages BuildKit's cross-compilation capabilities to generate a multi-platform manifest, as supported by the flags documented in docs/command-reference.md.

Exporting to Tarball

By default, container build writes type oci images to the local store. To export the image as a tarball for sharing or archiving, use the --output flag:

container build \
  --tag myorg/web-app:latest \
  --output type=tar,dest=./web-app.tar \
  .

Advanced Build Options

Multi-Stage and Secret-Aware Builds

BuildKit supports advanced Dockerfile features including multi-stage builds, build secrets, and cache control:

container build \
  --target production \
  --no-cache \
  --secret id=MY_API_KEY,env=API_KEY \
  --tag myorg/web-app:prod \
  .

This command builds only the production stage, bypasses the cache, and injects the API_KEY environment variable as a build secret without persisting it in the final image layers.

Verifying and Running Images

After building, verify the image exists in the local store:

container image list --quiet

Test the image immediately using container run:

container run -it myorg/web-app:latest

Summary

  • container build orchestrates BuildKit inside a lightweight VM to execute Dockerfiles and produce OCI-compliant images.
  • The builder VM runs the container-builder-shim image and is configured via ~/.config/container/config.toml in the [build] section.
  • Multi-architecture builds use the --arch and --platform flags to target multiple CPU architectures in a single invocation.
  • Output formats include the default OCI local store or tarball exports via --output type=tar,dest=....
  • Control resource allocation with container builder start --cpus and --memory, or set defaults in the configuration file.

Frequently Asked Questions

What is the builder shim image?

The builder shim is the container image ghcr.io/apple/container-builder-shim/builder:<tag> that runs inside the builder VM. It contains the BuildKit daemon and supporting tools necessary to execute builds. The specific version is controlled by the image key in the [build] section of your configuration file.

How do I change CPU and memory limits for builds?

You can specify resources temporarily when starting the builder with container builder start --cpus 8 --memory 32g, or permanently by setting cpus and memory values in the [build] section of ~/.config/container/config.toml. Changes to the configuration file require a builder restart to take effect.

Can I build images for Intel Macs from my Apple Silicon Mac?

Yes. Use the --arch amd64 flag (or --arch arm64 --arch amd64 for both) to cross-compile images for x86_64 architectures. BuildKit handles the cross-compilation automatically, and the resulting multi-platform image can run on both Apple Silicon and Intel systems.

How do I export a built image to a Docker-compatible tarball?

Use the --output flag with type tar: container build --output type=tar,dest=./image.tar .. This creates a tarball containing the OCI image layers and manifest, which can be imported into Docker or other container runtimes using standard docker load or similar commands.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →