I use Jenkins CI/CD platform for my hobby projects on aarch64 (linux/arm64v8) architecture. But I run these images on linux/amd64 at the most of time. So, I need to use multi-stage Dockerfile to build image for multi-platform. After some Google search and check results, I found a great blog post about this topic on the Docker website. The title of the article is Faster Multi-Platform Builds: Dockerfile Cross-Compilation Guide.
First of all, you can check on your OS and Docker environment, how to setup correctly the docker buildx, please see this builder toolkit page.
docker buildx ls
You can access the following build ARGs in your Dockerfile:
BUILDPLATFORM — matches the current machine. (e.g. linux/amd64) BUILDOS — os component of BUILDPLATFORM, e.g. linux BUILDARCH — e.g. amd64, arm64, riscv64 BUILDVARIANT — used to set ARM variant, e.g. v7 TARGETPLATFORM — The value set with --platform flag on build TARGETOS - OS component from --platform, e.g. linux TARGETARCH - Architecture from --platform, e.g. arm64 TARGETVARIANT
Here is the minimal setup for Dockerfile to test on your system.
FROM golang:alpine AS build ARG TARGETPLATFORM ARG BUILDPLATFORM RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log FROM alpine COPY /log /log
After you log in docker or private registry, run this command:
docker buildx build --platform linux/amd64,linux/arm64 --push .
Unfortunately, we can store multi-platform images only in registry.
Build multi-stage Dockerfile for golang app
FROM golang:1.17-alpine AS builder WORKDIR /src ARG TARGETOS TARGETARCH RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /out/myapp . FROM alpine as runner COPY /out/myapp /bin EXPOSE 8080 CMD ["myapp"]
If the programming languages and the native libraries don’t support cross-compilation, then there are still plenty of problems with it and the working solution isn’t simple.