How to Use Multi-Platform Images with `--platform`, `--os`, and `--arch` Flags in Apple Container
Use --platform for explicit os/arch[/variant] selection (highest priority), combine --os and --arch when omitting --platform, or set CONTAINER_DEFAULT_PLATFORM for persistent defaults.
The apple/container CLI supports multi-platform image workflows through three interrelated flags that control which operating system and architecture variant to pull, build, or run. Understanding the precedence between --platform, --os, and --arch ensures you target the correct image variant across different command contexts.
Platform Flag Precedence and Resolution Logic
The CLI resolves platform selection differently depending on whether you are fetching images or running containers. The core logic resides in Sources/Services/ContainerAPIService/Client/DefaultPlatform.swift, specifically in lines 65‑68 (image-fetch precedence) and 94‑98 (container-run precedence).
Image-Fetch Commands (pull, push, save)
For commands that transfer images between registries and local storage, the precedence flows from highest to lowest:
--platform– Explicit full specification (e.g.,linux/amd64)--osand--arch– Combined when--platformis omittedCONTAINER_DEFAULT_PLATFORM– Environment variable fallback- No platform – Requests all available platforms
As implemented in DefaultPlatform.swift (lines 65‑68), the CLI checks for --platform first, then constructs a platform string from the separate flags if provided.
Container Run Commands (run, create)
For runtime operations, the precedence shifts slightly to ensure containers can execute on the host:
--platform– Explicit overrideCONTAINER_DEFAULT_PLATFORM– Environment variable- Default values –
linux+ host architecture (when no flags or env var exist)
According to lines 94‑98 of DefaultPlatform.swift, the run and create commands use resolveWithDefaults, which falls back to the host's native architecture rather than requiring explicit flags.
Practical Usage Examples
Pulling Specific Platforms
Use --platform to extract a single variant from a multi-platform manifest:
# Pull only the linux/amd64 variant of nginx
container image pull --platform linux/amd64 nginx:latest
When --platform is present, the CLI ignores any separate --os or --arch values per the documentation in docs/command-reference.md (line 66).
Using Separate OS and Architecture Flags
When you omit --platform, combine --os and --arch to construct the platform specification:
# Equivalent to --platform linux/arm64
container image pull --os linux --arch arm64 nginx:latest
The CLI concatenates these values into a platform string before validation.
Environment Variable Defaults
Set CONTAINER_DEFAULT_PLATFORM to avoid repeating flags across commands:
export CONTAINER_DEFAULT_PLATFORM=linux/arm64
# Subsequent commands default to linux/arm64
container image pull nginx:latest
container run alpine:latest
The environment variable is consulted only after checking explicit flags, as handled by the fromEnvironment implementation in DefaultPlatform.swift.
Running Non-Native Platforms
Execute images built for different architectures than your host:
# Run an amd64 image on an arm64 Mac
container run --platform linux/amd64 alpine:latest uname -m
The run command validates the platform against available variants and uses emulation if necessary.
Mixed Flag Precedence
When flags conflict, --platform always wins:
# Results in linux/amd64, not linux/arm64
container run --os linux --arch arm64 --platform linux/amd64 busybox
This behavior aligns with the precedence hierarchy documented in docs/command-reference.md (lines 64‑66).
How Platform Resolution Works in the Source Code
When executing commands, the CLI invokes DefaultPlatform.resolve() (for image operations) or resolveWithDefaults() (for container operations). The resolution flow follows this strict order:
- Parse
--platformviaContainerizationOCI.Platform(from:)if the flag exists - Construct from parts if
--archor--osare provided individually - Check environment using
fromEnvironmentforCONTAINER_DEFAULT_PLATFORM - Apply defaults (run/create only) – fallback to
linuxand host architecture
The ContainerizationOCI.Platform parser (located in Sources/ContainerizationOCI/Platform.swift) validates the platform string and throws ContainerizationError.invalidArgument if the format is malformed, ensuring clear error messages for unsupported combinations.
Summary
- Use
--platformfor explicitos/arch[/variant]selection; it overrides all other platform flags according toDefaultPlatform.swiftlines 65‑68. - Combine
--osand--archwhen you need to specify components separately, but remember they are ignored if--platformis present. - Set
CONTAINER_DEFAULT_PLATFORMfor persistent defaults across sessions without typing flags repeatedly. - Remember the context difference: Image-fetch commands (pull, push) require explicit platform selection or default to all platforms, while run/create commands fall back to host defaults via
resolveWithDefaults(lines 94‑98).
Frequently Asked Questions
What happens if I use both --platform and --arch flags?
The --platform flag takes precedence and the --arch value is ignored. According to the precedence logic in DefaultPlatform.swift, the CLI checks for --platform first and only evaluates separate OS/arch flags when the full platform specification is absent.
Can I build multi-platform images using these flags?
Yes. The container build command accepts multiple --platform flags to create cross-platform images in a single invocation:
container build -t myapp:multi --platform linux/amd64 --platform linux/arm64 .
Why does my container run fail with "platform not supported"?
This occurs when the requested platform (via flag or environment variable) is not present in the image manifest. Verify available platforms with container image inspect, or omit platform flags to let the CLI select the host-compatible variant automatically.
How do I check which platform a container is actually using?
Inspect the container's configuration using container inspect <container-id> and look for the Platform field. If you ran the container without explicit flags, it will show the default linux/host-arch combination resolved by resolveWithDefaults in the source code.
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 →