Using Docker for Cross Platform Development Building Containers for Linux Windows and macOS
Streamline cross-platform development by building and running Docker containers on Linux, Windows, and macOS
Modern development teams often need to support applications that run on multiple platforms — Linux, Windows, and macOS. Maintaining platform-specific environments manually is error-prone and inefficient.
Docker provides a consistent way to package and run applications across different operating systems using containers. In this post, we’ll explore how to use Docker for cross-platform development, covering key concepts like multi-architecture images, buildx, and emulation using QEMU.
Why Cross-Platform Containers?
Building cross-platform containers allows you to:
- Develop on macOS or Windows, but deploy to Linux
- Test platform-specific logic in isolation
- Package and distribute consistent artifacts across CI/CD
- Simplify dependency management across OS boundaries
Key Concepts
- Base Images: Containers start from base images that are often OS and architecture specific.
- Image Architecture: E.g.,
linux/amd64
,linux/arm64
,windows/amd64
- Docker Buildx: Advanced build tool for building multi-platform images
- QEMU: Emulates CPU architecture differences when building cross-architecture containers
Setting Up Docker for Cross-Platform Builds
- Enable Docker BuildKit (already enabled in Docker Desktop):
export DOCKER_BUILDKIT=1
- Create a new buildx builder:
docker buildx create --name multiarch-builder --use
docker buildx inspect --bootstrap
- Install QEMU (for emulating different architectures):
On Docker Desktop (macOS/Windows), QEMU is preinstalled. On Linux:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
Building Multi-Platform Images
Let’s build an image that supports linux/amd64
and linux/arm64
:
docker buildx build --platform linux/amd64,linux/arm64 \
-t myapp:multiarch \
--push \
.
--platform
specifies target architectures--push
uploads the manifest to Docker Hub or registry
To build for Windows:
- Use
--platform windows/amd64
- Ensure the base image (e.g.,
mcr.microsoft.com/windows/servercore
) matches the host’s Windows version
docker buildx build --platform windows/amd64 -t myapp:win .
⚠️ Windows containers can only be built and run on Windows hosts with Windows containers enabled.
Example: Cross-Platform Dockerfile
FROM --platform=$BUILDPLATFORM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "index.js"]
Add platform awareness using $TARGETPLATFORM
and $BUILDPLATFORM
:
RUN echo "Building for $TARGETPLATFORM from $BUILDPLATFORM"
Running Containers on Different Platforms
- On Linux/macOS, containers are typically built for
linux/amd64
- On Apple Silicon (M1/M2), use
linux/arm64
or enable emulation foramd64
- On Windows, switch between Linux and Windows container engines via Docker Desktop
To test on a different architecture locally:
docker run --platform linux/arm64 myapp:multiarch
Testing with GitHub Actions (CI)
CI pipelines can automatically build multi-architecture images:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and Push
uses: docker/build-push-action@v3
with:
platforms: linux/amd64,linux/arm64
push: true
tags: user/myapp:latest
Best Practices
- Use multi-platform base images (e.g.,
node
,python
,openjdk
) - Avoid OS-specific dependencies when writing cross-platform Dockerfiles
- Use ARG TARGETPLATFORM to adjust logic per platform
- Automate builds with buildx and CI/CD pipelines
- Test your image on each target platform before production release
Conclusion
Cross-platform development with Docker allows you to build once and run anywhere — whether that’s Linux, macOS, or Windows. By using tools like Docker Buildx and QEMU, you can easily build and test containers for multiple architectures, streamline development workflows, and ensure your applications are truly portable.
Mastering this setup means your software will be future-proof and ready for the diverse infrastructure of modern DevOps and cloud environments.