How to Build OCI Images from Dockerfiles Using `container build`
container build is the primary CLI command in the Apple Container project that converts a Dockerfile and its associated build context into a standards-compliant OCI image by executing the build inside an isolated virtual machine.
The container build command provides a secure, reproducible method for transforming container definitions into runnable artifacts. As implemented in the apple/container open-source repository, this workflow leverages a dedicated builder virtual machine to isolate compilation processes from your host operating system. This architecture ensures consistent build environments across macOS, Linux, and Apple Silicon while maintaining the same runtime security model as regular containers.
Understanding the Builder VM Architecture
When you invoke container build, the CLI first checks for an active builder virtual machine. If none exists, it automatically provisions a lightweight VM optimized for container builds. According to the source documentation in docs/how-to.md, the default VM configuration allocates 2 GiB of RAM and 2 CPUs to handle standard build workloads.
The builder VM serves as an isolated execution environment that runs a container-based build engine. This isolation prevents build processes from affecting your host system and ensures that dependencies or tooling installed during the build do not pollute your local development environment. The VM leverages the same runtime security model as standard containers, providing defense-in-depth for arbitrary code execution during the build process.
How the Build Process Works
The container build command follows a streamlined pipeline to produce OCI-compliant images:
- Context Packaging – The specified directory (or current directory
.by default) is tar-packed and streamed into the builder VM. - Dockerfile Execution – The builder's internal Docker daemon reads the
Dockerfile(specified via--fileor defaulting toDockerfilein the root of the context) and processes each instruction sequentially. - Layer Creation – For each
RUN,COPY, andADDinstruction, the daemon creates new image layers according to the OCI image specification. - Manifest Assembly – The daemon assembles an OCI-compliant image manifest that combines all layers and metadata.
- Local Storage – The resulting image is stored in the local container image store and tagged according to your
-tor--tagspecifications.
As documented in docs/command-reference.md, the resulting images are fully compatible with the Open Container Initiative (OCI) standard, ensuring interoperability with other container runtimes and registries.
Essential Command-Line Options
The container build command supports several flags to control the build behavior:
| Option | Description |
|---|---|
-t, --tag <name> |
Tag the resulting image (supports multiple -t flags for multiple tags). |
-f, --file <path> |
Path to the Dockerfile (default: Dockerfile in the build context). |
--arch <arch> |
Target architecture(s); can be repeated for multi-arch builds. |
--build-arg <NAME=VAL> |
Pass build-time variables to the Dockerfile. |
--no-cache |
Disable layer caching for a clean rebuild. |
--target <stage> |
Build up to a specific multi-stage target. |
--debug |
Enable verbose output for troubleshooting. |
Configuring Builder Resources
For resource-intensive builds, you can provision a more powerful builder VM before executing your build. As detailed in docs/container-system-config.md, use the container builder start command to specify custom resource allocations:
container builder start --cpus 8 --memory 32g
This creates a builder with 8 CPU cores and 32 GiB of RAM, significantly improving build performance for complex applications. When finished building, terminate the VM to reclaim resources:
container builder stop
Multi-Architecture Support
The container build command supports cross-compilation for multiple architectures using the --arch flag. As noted in docs/how-to.md, you can specify multiple architectures in a single command to generate platform-specific variants:
container build \
--arch arm64 \
--arch amd64 \
--tag my-app:latest \
.
The builder automatically configures the appropriate cross-compilation environment for each target architecture, enabling you to produce Apple Silicon (arm64) and Intel (amd64) images from a single build invocation.
Step-by-Step Build Examples
Basic Build from Current Directory
Build an image using the default Dockerfile in the current directory:
container build -t my-app:latest .
Custom Dockerfile and Multiple Tags
Specify a non-standard Dockerfile name and apply multiple tags:
container build \
--file Dockerfile.prod \
-t my-app:prod \
-t my-app:1.0.0 \
.
Multi-Architecture Build with Registry Push
Build for multiple architectures and tag for a remote registry:
container build \
--arch arm64 \
--arch amd64 \
--tag registry.example.com/fido/web-test:latest \
--file Dockerfile \
.
Disable Rosetta on Apple Silicon
To build without using Rosetta translation on Apple Silicon Macs, modify ~/.config/container/config.toml:
builder.disableRosetta = true
Then execute the standard build command:
container build -t local/custom-init:latest .
Complete Workflow with Resource Management
For complex builds requiring significant resources:
# Start a high-performance builder
container builder start --cpus 8 --memory 32g
# Execute the build
container build \
--file Dockerfile \
--tag my-app:latest \
--no-cache \
.
# Stop the builder when complete
container builder stop
Summary
container buildconverts Dockerfiles into OCI-compliant images using an isolated builder VM.- The builder VM defaults to 2 GiB RAM and 2 CPUs, configurable via
container builder start. - Build contexts are automatically tar-packed and streamed into the builder's Docker daemon.
- The
--archflag enables multi-architecture builds forarm64,amd64, and other targets. - Configuration options in
~/.config/container/config.tomlcontrol advanced behaviors like Rosetta translation. - Complete documentation exists in
docs/command-reference.mdanddocs/how-to.md.
Frequently Asked Questions
What is the default resource allocation for the builder VM?
The builder VM provisions with 2 GiB of RAM and 2 CPUs by default. You can override these defaults using container builder start --cpus <n> --memory <size> before running your build, as documented in docs/how-to.md.
How do I disable Rosetta on Apple Silicon builds?
Add builder.disableRosetta = true to your ~/.config/container/config.toml configuration file. This setting forces the builder to use native ARM instructions rather than x86_64 translation during the build process.
Can I build for multiple architectures simultaneously?
Yes. Pass multiple --arch flags (e.g., --arch arm64 --arch amd64) to create images for different processor architectures in a single build invocation. The builder handles cross-compilation automatically.
Where is the container build command documented?
Complete syntax and option descriptions are available in docs/command-reference.md within the repository. High-level workflow guidance and builder VM lifecycle management are covered in docs/how-to.md.
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 →