Skip to content

Instantly share code, notes, and snippets.

@AverageMarcus
Created September 2, 2021 08:49
Show Gist options
  • Save AverageMarcus/78fbcf45e72e09d9d5e75924f0db4573 to your computer and use it in GitHub Desktop.
Save AverageMarcus/78fbcf45e72e09d9d5e75924f0db4573 to your computer and use it in GitHub Desktop.
Example multi-arch Dockerfile for Go projects
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.16 as builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app/
ADD . .
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-w -s" -o yourapplication main.go
FROM --platform=${TARGETPLATFORM:-linux/amd64} scratch
WORKDIR /app/
COPY --from=builder /app/yourapplication /app/yourapplication
ENTRYPOINT ["/app/yourapplication"]
.DEFAULT_GOAL := default
IMAGE ?= yourapplication:latest
export DOCKER_CLI_EXPERIMENTAL=enabled
.PHONY: build # Build the container image
build:
@docker buildx create --use --name=crossplat --node=crossplat && \
docker buildx build \
--output "type=docker,push=false" \
--tag $(IMAGE) \
.
.PHONY: publish # Push the image to the remote registry
publish:
@docker buildx create --use --name=crossplat --node=crossplat && \
docker buildx build \
--platform linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x \
--output "type=image,push=true" \
--tag $(IMAGE) \
.
@akatona84
Copy link

I might be wrong, but according to docker docs BUILDPLATFORM should be defined as ARG before the first FROM too.
https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact

@AverageMarcus
Copy link
Author

It's been a while since I looked at this but I have this setup in one of my projects that is working at least when it last built a couple years ago - https://github.com/AverageMarcus/kube-image-prefetch/blob/master/Dockerfile

@akatona84
Copy link

You're correct, sorry, these args are defined by docker. When I declared them before FROM, they became empty. Thanks for this example, helped me a lot.

@AverageMarcus
Copy link
Author

I’m so glad to hear that! 😁

@cherrymu
Copy link

cherrymu commented Aug 9, 2024

@AverageMarcus I am trying to understand from your above Makefile what is the difference between build and publish as both looks pretty same except platform difference.

@AverageMarcus
Copy link
Author

@cherrymu The --output is what makes the difference.

--output "type=image,push=true" 

This instructs the command to push to the remote registry whereas this..

--output "type=docker,push=false"

...just builds the image on the local machine.

@cherrymu
Copy link

cherrymu commented Aug 9, 2024

Thanks @AverageMarcus for clarifying it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment