How to Build and Run Multi-Platform (arm64/amd64) Images with container
You can build multi-platform container images by passing multiple --arch flags to container build, which creates a manifest list supporting both arm64 and amd64 architectures that the CLI automatically selects from at runtime.
The container tool from Apple's open-source repository generates OCI-compatible images that bundle multiple architectures into a single manifest. Building multi-platform container images allows you to support both Apple Silicon (arm64) and Intel-based (amd64) systems from one tagged image. This eliminates the need to maintain separate build pipelines for different host architectures.
Building Multi-Platform Images
Specifying Target Architectures
To create a multi-architecture image, invoke container build with the --arch flag for each target platform. According to the implementation in Sources/Services/MachineAPIService/Client/Flags.swift (lines 30-31), the CLI accepts multiple architecture specifications and aggregates them into a single build request.
container build \
--arch arm64 \
--arch amd64 \
--tag registry.example.com/app:latest \
--file Dockerfile .
This produces a manifest list where a single tag references separate image layers for each specified architecture.
Manifest List Creation
The build process generates an OCI-compliant manifest list that aggregates per-architecture images. When you specify multiple --arch flags, the builder creates distinct image layers for each platform and bundles them under one reference, as documented in the official how-to guide at docs/how-to.md (lines 63-71).
Running Multi-Platform Images
Automatic Architecture Selection
When executing container run, the CLI automatically selects the image variant matching the host's architecture. The platform resolution logic in Sources/Services/ContainerImagesService/Server/SnapshotStore.swift (lines 66-71) calls image.descriptor(for: platform) to retrieve the correct manifest entry for the current machine.
container run --rm registry.example.com/app:latest uname -a
Overriding the Platform at Runtime
You can force a specific architecture using the --arch flag or the --platform flag. The --platform option is documented in docs/command-reference.md (line 155) and accepts values in the format os/arch[/variant]. This overrides automatic detection and executes the container using the specified variant.
container run --arch arm64 --rm registry.example.com/app:latest uname -a
container run --arch amd64 --rm registry.example.com/app:latest uname -a
Implementation Details
Platform Configuration Structure
The underlying data model for platform information is defined in Sources/Services/MachineAPIService/Client/MachineConfiguration.swift (lines 55-95). The ContainerizationOCI.Platform struct encapsulates the operating system, architecture, and variant fields used throughout the build and runtime pipeline.
CLI Flag Parsing
The MachineAPIService client parses platform specifications through Flags.swift (lines 30-31), converting command-line arguments into structured platform objects. These objects determine which architecture-specific image layers the builder produces and the runtime selects.
Image Resolution Mechanics
When the MachineAPIService processes a build or run request, it queries the SnapshotStore to locate the appropriate architecture-specific image descriptor. This ensures that the correct binary format is extracted and executed for the requested platform.
Pushing Multi-Platform Images
Pushing a multi-platform image uploads the entire manifest list and all architecture variants in one operation. The registry stores the manifest list, allowing clients to pull only the layers matching their local platform.
container image push registry.example.com/app:latest
Pulling works identically—clients automatically receive the correct variant for their architecture without additional flags.
Summary
- Build multi-platform images by passing multiple
--archflags tocontainer build - A single tag references a manifest list containing separate images for arm64 and amd64
- The CLI automatically selects the matching architecture at runtime unless overridden with
--archor--platform - Platform data is structured in
MachineConfiguration.swiftand parsed viaFlags.swift - Push and pull operations handle all variants transparently through the manifest list
Frequently Asked Questions
How do I build for both arm64 and amd64 simultaneously?
Pass the --arch flag multiple times when running container build. The command aggregates all specified architectures into a single manifest list. For example: container build --arch arm64 --arch amd64 --tag myapp:latest .
Can I run an amd64 container on an arm64 Mac using this tool?
Yes. Use the --arch amd64 flag with container run to force execution of the x86-64 variant. According to the command reference in docs/command-reference.md, this overrides the automatic platform detection provided by the MachineAPIService.
Where does the tool store platform information during builds?
The platform configuration is managed through the ContainerizationOCI.Platform struct in Sources/Services/MachineAPIService/Client/MachineConfiguration.swift (lines 55-95). The CLI parses these values from flags and passes them to the builder service.
Do I need separate tags for each architecture?
No. The container tool creates a manifest list where one tag references multiple architecture-specific images. When you push that tag, all variants upload together, and clients automatically pull the correct variant for their host architecture.
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 →