Home Explore Blog CI



docker

6th chunk of `content/manuals/build/building/multi-platform.md`
992d320b8c72d0ecb0afe2c5aa35a7c92a69d9edb43d533b0000000100000e64
In Go, you can use the `GOOS` and `GOARCH` environment variables to specify the
target platform to build for.

Prerequisites:

- Docker Desktop or Docker Engine

Steps:

1. Create an empty directory and navigate to it:

   ```console
   $ mkdir go-server
   $ cd go-server
   ```

2. Create a base Dockerfile that builds the Go application:

   ```dockerfile
   # syntax=docker/dockerfile:1
   FROM golang:alpine AS build
   WORKDIR /app
   ADD https://github.com/dvdksn/buildme.git#eb6279e0ad8a10003718656c6867539bd9426ad8 .
   RUN go build -o server .
   
   FROM alpine
   COPY --from=build /app/server /server
   ENTRYPOINT ["/server"]
   ```

   This Dockerfile can't build multi-platform with cross-compilation yet. If
   you were to try to build this Dockerfile with `docker build`, the builder
   would attempt to use emulation to build the image for the specified
   platforms.

3. To add cross-compilation support, update the Dockerfile to use the
   pre-defined `BUILDPLATFORM` and `TARGETPLATFORM` build arguments. These
   arguments are automatically available in the Dockerfile when you use the
   `--platform` flag with `docker build`.

   - Pin the `golang` image to the platform of the builder using the
     `--platform=$BUILDPLATFORM` option.
   - Add `ARG` instructions for the Go compilation stages to make the
     `TARGETOS` and `TARGETARCH` build arguments available to the commands in
     this stage.
   - Set the `GOOS` and `GOARCH` environment variables to the values of
     `TARGETOS` and `TARGETARCH`. The Go compiler uses these variables to do
     cross-compilation.

   {{< tabs >}}
   {{< tab name="Updated Dockerfile" >}}

   ```dockerfile
   # syntax=docker/dockerfile:1
   FROM --platform=$BUILDPLATFORM golang:alpine AS build
   ARG TARGETOS
   ARG TARGETARCH
   WORKDIR /app
   ADD https://github.com/dvdksn/buildme.git#eb6279e0ad8a10003718656c6867539bd9426ad8 .
   RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o server .
   
   FROM alpine
   COPY --from=build /app/server /server
   ENTRYPOINT ["/server"]
   ```

   {{< /tab >}}
   {{< tab name="Old Dockerfile" >}}

   ```dockerfile
   # syntax=docker/dockerfile:1
   FROM golang:alpine AS build
   WORKDIR /app
   ADD https://github.com/dvdksn/buildme.git#eb6279e0ad8a10003718656c6867539bd9426ad8 .
   RUN go build -o server .
   
   FROM alpine
   COPY --from=build /app/server /server
   ENTRYPOINT ["/server"]
   ```

   {{< /tab >}}
   {{< tab name="Diff" >}}

   ```diff
   # syntax=docker/dockerfile:1
   -FROM golang:alpine AS build
   +FROM --platform=$BUILDPLATFORM golang:alpine AS build
   +ARG TARGETOS
   +ARG TARGETARCH
   WORKDIR /app
   ADD https://github.com/dvdksn/buildme.git#eb6279e0ad8a10003718656c6867539bd9426ad8 .
   -RUN go build -o server .
   +RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o server .
   
   FROM alpine
   COPY --from=build /app/server /server
   ENTRYPOINT ["/server"]
   ```

   {{< /tab >}}
   {{< /tabs >}}

4. Build the image for `linux/amd64` and `linux/arm64`:

   ```console
   $ docker build --platform linux/amd64,linux/arm64 -t go-server .
   ```

This example has shown how to cross-compile a Go application for multiple
platforms with Docker builds. The specific steps on how to do cross-compilation
may vary depending on the programming language you're using. Consult the
documentation for your programming language to learn more about cross-compiling
for different platforms.

> [!TIP]
> You may also want to consider checking out
> [xx - Dockerfile cross-compilation helpers](https://github.com/tonistiigi/xx).
> `xx` is a Docker image containing utility scripts that make cross-compiling with Docker builds easier.

Title: Cross-Compiling Go Application with Dockerfile Updates
Summary
This section outlines how to update a Dockerfile to support cross-compilation of a Go application for multiple platforms. It emphasizes using `BUILDPLATFORM` to pin the golang image and introduces `TARGETOS` and `TARGETARCH` arguments to set `GOOS` and `GOARCH` environment variables, enabling the Go compiler to cross-compile. A diff is provided, highlighting the changes made to the Dockerfile. The command to build the image for both `linux/amd64` and `linux/arm64` is also included. Finally, it recommends exploring the `xx` Docker image for cross-compilation helpers.