Docker Desktop on Apple silicon makes image architecture explicit
Docker Desktop is generally available for Apple silicon. Native arm64 development makes the distinction between a local build machine and a deployment target harder to ignore.
A development machine and a deployment target can now differ in architecture without requiring a separate container workflow. Docker's April 15 announcement makes Docker Desktop for Apple silicon generally available. The release supports building and running arm64 and amd64 images. That gives M1 users a local development environment, but it also makes architecture an explicit part of understanding which image a build produces.
The announcement follows developer previews and release candidates. Docker reports 45,000 preview downloads and 140 public bug reports during that process. Those figures describe participation in the preview, rather than evidence that every workload behaves identically across architectures. The important engineering question is how a build reaches its intended target when the machine running the build has changed.
I value Docker's repeatable build description, particularly for a service delivered as a small final image. An architecture change makes the assumptions in that description easier to see. The image still has to contain a program that can execute on the machine where it will run.
The target belongs to the build
The contemporary Buildx documentation describes --platform as selecting the target for the build output. Dockerfile FROM instructions without their own platform selection use that target when resolving base images. The output platform is also the selected target. A build therefore involves more than choosing the architecture of the final executable.
An instruction that runs a program needs execution support for that program's platform. The documentation states that a clean setup can execute build instructions only for its own architecture. Additional registered binary handlers can provide support for other architectures. Docker Desktop supplies that integration, which is why a developer can use familiar build commands without separately assembling an emulation environment.
This distinction matters for dependency installation as well as compilation. A RUN instruction may execute tools contained in the selected base image. Choosing an amd64 target on an arm64 machine can therefore require emulation before the application compiler is even invoked. Selecting a platform names the desired result, while execution support determines how the builder can carry out the required instructions.
Buildx always uses BuildKit. It is a Docker CLI plugin with commands for creating and selecting builder instances, including builders backed by remote nodes. The local laptop is one possible place to perform the work, but it is not built into the meaning of the target platform.
Emulation preserves a familiar build description
The Buildx guide describes QEMU emulation as the easiest route when the builder already supports it. BuildKit detects the available secondary architectures and uses the registered binary handler when an instruction needs to execute a foreign binary. The integration uses the kernel's binfmt_misc mechanism. Docker Desktop comes with the required registration for additional platforms.
The attraction is that the same Dockerfile can continue to execute its ordinary target-platform tools. A package manager inside a target base image still runs as that program. The builder supplies the execution mechanism. This reduces the amount of architecture-specific orchestration a developer must write just to obtain an initial working build.
That convenience does not make emulated execution equivalent to native execution. The Buildx documentation recommends multiple native nodes for complicated cases QEMU does not handle and says those nodes generally perform better. It supplies no universal performance ratio. The useful claim is that native workers provide another execution strategy when emulation is an unsuitable implementation of a build step.
For local development, this means that being able to launch an image and choosing an efficient way to build it are related but separate concerns. Desktop's support makes foreign-platform execution available. A build that performs substantial compilation may still benefit from choosing a different strategy for the compiler work.
Native nodes and cross-compilation change where work happens
Buildx can combine native nodes in one builder instance. Its documented workflow creates a builder using one Docker context and appends another node using a second context. A multi-platform request can then use machines that execute the relevant architectures natively. This adds infrastructure to manage, but it keeps the build commands inside their native execution environments.
Cross-compilation is another option when the language and build dependencies support it. Here a stage runs on the build machine's platform while its compiler emits output for the requested target. Buildx exposes automatic platform arguments, including BUILDPLATFORM and TARGETPLATFORM, for expressing that relationship in a multi-stage Dockerfile.
The source documentation illustrates the distinction with a build stage pinned to BUILDPLATFORM. Declaring an argument makes its value available to commands inside the stage. The compiler or build script must then use the target information correctly. Merely selecting a native build stage does not tell an arbitrary compiler which machine its output must run on.
I prefer to keep this decision visible in the build file. A native compiler targeting another architecture and a foreign compiler running under emulation can produce an artifact for the same target, but they execute different programs along the way. Understanding that difference makes dependency assumptions and build costs easier to explain.
One image reference can describe several platform images
Multi-platform output also needs a representation that preserves its distinct artifacts. Buildx documents support for requesting several platforms together with the docker-container driver. The result is a manifest list containing the images for the requested architectures. A registry can publish that list under one reference, and Docker selects the appropriate image for the node running it.
The existing schema 2 manifest specification explains the structure. Each manifest list entry has a platform description and a descriptor identifying the corresponding image manifest. The platform includes operating system and architecture. The descriptor includes the object's media type, byte size and digest.
Each selected image manifest then references its own configuration object and ordered layers. A shared tag is therefore a reference to a selection structure, rather than evidence that identical executable bytes run on every platform. This is how one repository can distribute several appropriate images while preserving content identity for the individual objects.
That model helps explain what should be verified when publishing multi-platform output. The list must contain the intended platform entries, and each entry needs to identify the corresponding image. A successful local run establishes something about the selected local platform. It cannot establish that another entry contains the intended program for a different architecture.
The output destination matters
Buildx's driver and exporter determine where the result goes. The documented docker driver adds its built images to the local Docker image view. Other drivers require an output choice. The docker-container driver supports the multi-platform workflow, while the Docker exporter described in these documents supports only a single-platform result.
For a multi-platform result, the documentation identifies pushing directly to a registry as the common route. This example assumes a project with an appropriate Dockerfile, access to the named registry repository and execution support for the requested platforms:
docker buildx create --name multiplatform --driver docker-container --use
docker buildx build --platform linux/amd64,linux/arm64 \
--tag registry.example.com/team/service:example --push .
docker buildx rm multiplatform
The final command removes the builder instance created for the example. Publishing sends the output to the configured registry, so the command deploys build artifacts. That destination matters when adapting an example to an actual development environment.
The documented inspection command, docker buildx inspect --bootstrap, reports the runtime platforms a builder supports. That information describes execution capability at the selected builder. It is useful alongside the explicit --platform request because the requested target and the available workers are separate inputs. A builder chosen through docker buildx use remains selected for later build commands, so the current builder is part of understanding a subsequent invocation as well.
General availability still has documented limits
The Desktop 3.3.1 release notes identify April 15 as the release that makes Desktop available for both Apple silicon and Intel chips. They also record reduced idle CPU consumption on Apple silicon. The same entry lists networking limitations, including internet ping behavior and occasional data loss when a TCP stream is half-closed.
Those limits belong to the released environment and should remain distinct from image architecture selection. Choosing the correct arm64 image does not change the documented networking behavior around it. Apple silicon support gives developers another native host platform, while Buildx and manifest lists provide explicit ways to construct and distribute the corresponding deployment artifacts.