How to Build Container Images Using BuildKit with Apple's Container
Apple Container automates BuildKit integration by provisioning a VM-based builder container that compiles Dockerfiles into OCI images via a vsock connection, requiring only a single container build command to initiate the entire workflow.
Apple Container (available at apple/container) provides a native macOS container runtime that leverages BuildKit as an isolated builder. When you execute container build, the CLI automatically manages the builder lifecycle, from downloading the BuildKit image to bootstrapping the VM, allowing you to build container images using BuildKit with Apple's container without manual setup.
How the BuildKit Builder Works
The architecture relies on three coordinated components that handle provisioning, CLI parsing, and communication.
The BuilderStart Command
At Sources/ContainerCommands/Builder/BuilderStart.swift, the BuilderStart command orchestrates the builder lifecycle. If the system detects that the buildkit container is missing or its configuration has changed (e.g., CPU or memory limits), the tool performs the following steps:
- Downloads the BuildKit image specified in
containerSystemConfig.build.image. - Unpacks the image into a temporary snapshot.
- Creates a VM-based container running the
container-builder-shimbinary alongside the BuildKit daemon. - Bootstraps the container, forwarding environment variables like
BUILDKIT_COLORS,NO_COLOR, and optionallySSH_AUTH_SOCK. - Starts the BuildKit process listening on a vsock connection at port 8088.
This process is fully automated—you never need to manually start the builder before running a build.
The BuildCommand Frontend
The BuildCommand at Sources/ContainerCommands/BuildCommand.swift serves as the CLI entry point for container build. It parses flags (such as --cpus, --memory, and --build-arg), establishes the vsock connection to the builder, and constructs a Builder object that invokes the BuildKit API. This component translates your local directory context and Dockerfile into an OCI-compliant image.
The Builder Shim and vsock Communication
Inside the VM, the container-builder-shim binary (located at /usr/local/bin/container-builder-shim within the BuildKit image) forwards traffic between the BuildKit daemon and the host via vsock. This socket-based communication avoids network complexity while maintaining isolation between the build process and the host system.
Running Your First Build
To build container images using BuildKit with Apple's container, navigate to a directory containing a Dockerfile and run:
container build -t my-app:latest .
The CLI automatically provisions the builder if it does not exist, then compiles the image.
Specifying Custom Resources
Control builder allocation using the --cpus and --memory flags, which are defined in the ContainerSystemConfig and enforced by the BuilderStart logic:
container build \
-f Dockerfile.prod \
-t my-app:prod \
--cpus 4 \
--memory 8G \
.
Passing Build Arguments and Secrets
Leverage standard BuildKit features for secure builds:
container build \
--build-arg NODE_VERSION=20 \
--secret id=npm_token,env=NPM_TOKEN \
-t my-node-app .
Adjusting Output Verbosity
Limit log output while maintaining progress visibility:
container build --progress plain -q -t quiet-image .
Managing the Builder Lifecycle
The builder persists between builds to avoid re-downloading images. To force a fresh environment—for example, after updating the BuildKit image in your ContainerSystemConfig—stop and delete the existing builder:
container builder stop
container builder delete --force
container build -t fresh-image .
Upon deletion, the next container build invocation triggers BuilderStart to recreate the VM with the latest configuration.
Summary
- Automatic provisioning: The
BuilderStartcommand atSources/ContainerCommands/Builder/BuilderStart.swiftdownloads, unpacks, and boots the BuildKit VM when you runcontainer build. - vsock communication: The builder uses port 8088 via
container-builder-shimto securely forward BuildKit API calls between the host and VM. - Resource control: Specify CPU and memory limits with
--cpusand--memoryflags, stored inContainerSystemConfig. - Lifecycle management: Use
container builder stopandcontainer builder delete --forceto reset the builder state and force reconfiguration.
Frequently Asked Questions
How does Apple Container handle the BuildKit image download?
The tool checks containerSystemConfig.build.image (defined in Sources/ContainerPersistence/ContainerSystemConfig.swift) to determine which BuildKit image to fetch. If the builder container is missing or its configuration differs from the current system settings, BuilderStart automatically downloads and unpacks the image into a temporary snapshot before creating the VM.
What is the purpose of the container-builder-shim binary?
The container-builder-shim binary runs inside the VM at /usr/local/bin/container-builder-shim and acts as a bridge between the BuildKit daemon and the host. It forwards traffic over vsock (port 8088), allowing the host-side BuildCommand to communicate with the isolated builder without exposing network interfaces.
Can I use SSH agents during the build process?
Yes. The BuilderStart command automatically forwards SSH_AUTH_SOCK into the builder container environment if it is set on the host. This allows BuildKit to use SSH keys for cloning private repositories during the build, without requiring manual key injection.
Where are the available build options documented?
The complete list of container build flags—including --build-arg, --secret, --progress, and resource limits—is documented in docs/command-reference.md within the repository. This file details how the BuildCommand interprets each flag and passes it to the BuildKit API.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →