Cross-compiling Go for Docker on ARM64 with CGO_ENABLED=1

David Michael
CRYPDEX
Published in
2 min readFeb 21, 2019

Challenge: On your x86 machine, create a Docker image to be run on an ARM64 with a Go application that compiles libraries with CGO.

For the solution, I am going to keep it simple and assume you are working with Docker for Mac, though this will likely work on other platforms. The primary advantage of Docker for Mac for now is the ability to run the ARM64 image that is produced on the Mac host without any additional setup (if you are on Linux please see the references).

The core of creating ARM64 images is fairly simple and consists of

  • Using an ARM64 base image
  • Using the correct env vars when building the Go application

The real trick is when a package in you application needs CGO (like Ethereum for instance). For this, your Dockerfile recipe needs to install a cross compiler.

Here is what a Dockerfile might look like

FROM golang:1.11 AS builder

# Magic line, notice in use that the lib name is different!
RUN apt-get update && apt-get install -y gcc-aarch64-linux-gnu# Add your app and do what you need to for dependenciesADD . /go/src/github.com/org/repo
WORKDIR /go/src/github.com/go/repo
RUN CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc GOOS=linux GOARCH=arm64 go build -o app .

# Final stage - pick any old arm64 image you want
FROM multiarch/ubuntu-core:arm64-bionic

WORKDIR /root/

COPY --from=builder /go/src/github.com/org/repo/app .
CMD ["./app"]

The key here is to install the cross-compiler for the build stage. In the example above it is gcc-aarch64-linux-gnu

Happy building!

Here are some references that might help to grok the situation you may be in

--

--