AWS ECR multiarch containers and Go
version 1.0, 2023-03-08
Table of Contents
|
Note
|
For this example I am using a personal ECR repo where I put multiple images so adjust the tagging accordingly. |
Before adjusting my Dockerfile to use multiarch I was building for ARM64 and getting the following error on execution:
standard_init_linux.go:228: exec user process caused: exec format error
The Dockerfile
This example clones a repo, and builds a Go binary using the GOARCH=${arch} ENV var:
ARG arch
FROM --platform=linux/${arch} golang:1.20.1 as builder
WORKDIR /workdir
ENV CFSSL_VERSION=v1.6.3
RUN git clone https://github.com/cloudflare/cfssl_trust.git /etc/cfssl && \
git clone https://github.com/cloudflare/cfssl.git --branch ${CFSSL_VERSION} && \
cd cfssl && \
GOOS=linux GOARCH=${arch} go build -ldflags "-s -w -X github.com/cloudflare/cfssl/cli/version.version=${CFSSL_VERSION}" -o bin/cfssl ./cmd/cfssl
FROM --platform=linux/${arch} ubuntu:22.04
WORKDIR /workdir
COPY --from=builder /workdir/cfssl/bin/* /usr/bin/
COPY --from=builder /etc/cfssl /etc/cfssl
COPY ./server/ca-key.pem .
COPY ./server/ca.pem .
COPY ./server/config.json .
COPY ./docker-entrypoint.sh .
EXPOSE 8080
ENTRYPOINT ["/workdir/docker-entrypoint.sh"]
|
Note
|
Both containers, not just the builder need to have the --platform flag. |
The build commands
docker build -t xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-amd64 --build-arg arch=amd64 .
docker build -t xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-arm64 --build-arg arch=arm64 .
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin xxx.dkr.ecr.us-west-2.amazonaws.com
docker push xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-amd64
docker push xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-arm64
docker manifest create xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3 \
xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-amd64 \
xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-arm64 || true
docker manifest annotate --arch amd64 xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3 \
xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-amd64
docker manifest annotate --arch arm64 xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3 \
xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3-arm64
docker manifest push xxx.dkr.ecr.us-west-2.amazonaws.com/dgamba:cfssl-1.6.3-3
|
Note
|
I needed to push the individual images before I could create the manifest. |
Running amd64 images on MacOS M1
You have 2 options:
export DOCKER_DEFAULT_PLATFORM=linux/amd64
or
docker run --platform linux/amd64 -d -t ubuntu:22.04
Or you can mix them ;-)
DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --platform linux/amd64 -d -t ubuntu:22.04
|
Note
|
Keep in mind you might need to delete your images if they are already downloaded: |
docker image rm <image>