# How to Build Custom Container Images Using BuildKit Integration with apple/container

> Learn to build custom container images with apple/container and BuildKit. Execute a simple command to provision a VM, forward your context, and compile your Dockerfile into an OCI image.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-22

---

**To build custom container images using BuildKit integration with apple/container, execute `container build -t <image>:<tag> .` and the CLI automatically provisions an isolated BuildKit VM, forwards your build context via vsock port 8088, and compiles your Dockerfile into an OCI-compliant image.**

The **apple/container** repository provides a native container management solution for Apple silicon that leverages **BuildKit** as an isolated builder container. When you build custom container images using BuildKit integration with apple/container, the toolchain automates VM provisioning, image fetching, and vsock-based communication between the host and builder. This architecture delivers reproducible OCI image builds without requiring manual Docker daemon management or complex configuration.

## How the BuildKit Integration Works in apple/container

The integration orchestrates a lightweight, VM-based BuildKit container that handles all image compilation tasks. According to the apple/container source code, the process involves automated lifecycle management and vsock-based IPC.

### The Builder Lifecycle (BuilderStart.swift)

In [`Sources/ContainerCommands/Builder/BuilderStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Builder/BuilderStart.swift), the `BuilderStart` command manages the complete lifecycle of the BuildKit builder container. When you invoke `container build`, the CLI checks for a running builder container named `buildkit`. If absent or misconfigured, the system automatically downloads the BuildKit image specified in `containerSystemConfig.build.image`, unpacks it into a temporary snapshot, and creates a VM-based container running the `container-builder-shim` binary alongside the BuildKit daemon.

The bootstrap process forwards critical environment variables—including `BUILDKIT_COLORS`, `NO_COLOR`, and optional `SSH_AUTH_SOCK`—into the container. The BuildKit process starts via a vsock connection on port 8088, enabling secure host-to-VM communication without network exposure.

### The Build Command Execution (BuildCommand.swift)

The `BuildCommand` in [`Sources/ContainerCommands/BuildCommand.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/BuildCommand.swift) serves as the CLI front-end that drives the actual compilation. This command dials the vsock connection, instantiates a `Builder` object, and invokes BuildKit's API to transform your Dockerfile or Containerfile into an OCI image. The implementation handles flag parsing, context preparation, and resource limit enforcement.

## Configuration and System Defaults

Builder behavior is controlled through the **ContainerSystemConfig** definition found under `Sources/ContainerPersistence/`. This configuration stores defaults for builder CPU allocation, memory limits, Rosetta usage, and the BuildKit image name loaded via `Application.loadContainerSystemConfig()`. You can override these defaults per-build using command-line flags.

## Building Container Images: Practical Examples

The `container build` command supports standard Dockerfile workflows with apple/container-specific optimizations for Apple silicon.

### Basic Build from Current Directory

To build and tag an image from a Dockerfile in your current working directory:

```bash
container build -t my-app:latest .

```

The CLI automatically starts the `buildkit` builder container if it does not exist, then executes the build.

### Custom Dockerfile and Resource Allocation

Specify alternative Dockerfiles and allocate additional CPU or memory to the builder VM:

```bash
container build \
    -f Dockerfile.prod \
    -t my-app:prod \
    -c 4 \
    -m 8G \
    .

```

The `-c` flag sets CPU cores and `-m` sets memory for the BuildKit VM, directly mapping to the resource constraints managed by `BuilderStart`.

### Build Arguments and Secrets

Pass build-time variables and sensitive data securely:

```bash
container build \
    --build-arg NODE_VERSION=20 \
    --secret id=npm_token,env=NPM_TOKEN \
    -t my-node-app .

```

These flags are parsed by [`BuildCommand.swift`](https://github.com/apple/container/blob/main/BuildCommand.swift) and forwarded to the BuildKit daemon via the vsock connection.

### Rebuilding the Builder Container

Force a fresh builder after changing the BuildKit image or resource defaults:

```bash
container builder stop
container builder delete --force
container build -t fresh-image .

```

This sequence ensures the CLI recreates the builder with updated settings from `ContainerSystemConfig`.

### Quiet and Plain Progress Output

Suppress verbose logs while monitoring build progress:

```bash
container build --progress plain -q -t quiet-image .

```

## Key Architectural Components

Understanding the source structure helps debug complex builds:

- **[`Sources/ContainerCommands/Builder/BuilderStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Builder/BuilderStart.swift)**: Implements builder lifecycle, image fetching, DNS configuration, and Rosetta support.
- **[`Sources/ContainerCommands/BuildCommand.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/BuildCommand.swift)**: Parses CLI arguments and orchestrates the BuildKit client connection.
- **[`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift)**: Defines default builder parameters including image URLs and resource limits.
- **[`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md)**: Documents the complete `container build` flag reference and BuildKit workflow.

The `container-builder-shim` binary (`/usr/local/bin/container-builder-shim`) runs inside the VM and forwards BuildKit traffic to the host via vsock.

## Summary

- **apple/container** automates BuildKit VM provisioning when you run `container build`, eliminating manual builder setup.
- The `BuilderStart` command in [`BuilderStart.swift`](https://github.com/apple/container/blob/main/BuilderStart.swift) handles image downloads, VM creation, and vsock initialization on port 8088.
- [`BuildCommand.swift`](https://github.com/apple/container/blob/main/BuildCommand.swift) drives the build process, translating CLI flags into BuildKit API calls.
- Resource limits (`--cpus`, `--memory`) and configuration defaults are managed through `ContainerSystemConfig`.
- The `container-builder-shim` binary facilitates secure communication between the host CLI and the BuildKit daemon.

## Frequently Asked Questions

### How does apple/container automatically start the BuildKit builder?

When you execute `container build`, the CLI checks for a running container named `buildkit`. If missing, it downloads the image defined in `containerSystemConfig.build.image`, unpacks it to a temporary snapshot, and boots a VM running the `container-builder-shim` and BuildKit daemon. This automation is implemented in [`BuilderStart.swift`](https://github.com/apple/container/blob/main/BuilderStart.swift).

### What port does BuildKit use for communication in apple/container?

The BuildKit daemon communicates with the host via **vsock port 8088**. The `container-builder-shim` binary inside the VM forwards traffic between the BuildKit process and the host CLI through this socket.

### How do I force apple/container to recreate the BuildKit builder?

Run `container builder stop` followed by `container builder delete --force` to remove the existing builder. The next `container build` invocation will automatically provision a fresh builder VM with current configuration settings.

### Can I use SSH keys during builds with apple/container?

Yes. If `SSH_AUTH_SOCK` is set in your environment, [`BuilderStart.swift`](https://github.com/apple/container/blob/main/BuilderStart.swift) automatically forwards this variable into the builder container, allowing BuildKit to access your SSH agent for fetching private Git repositories during the build.