From 6aee150cd08241da74e67f15a26a77240e0ce79b Mon Sep 17 00:00:00 2001 From: Mike Tougeron Date: Sat, 15 Jan 2022 16:53:11 -0800 Subject: [PATCH] Multi-arch builds for goldpinger Signed-off-by: Mike Tougeron --- .github/workflows/publish.yml | 64 +++++++++++++++++++++++++++++++++++ Dockerfile | 17 +++++++--- Makefile | 35 +++++++------------ README.md | 18 +++++----- build/build.sh | 8 ++--- docker_deploy.sh | 6 +--- go.mod | 2 +- 7 files changed, 100 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..0eff9ec --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,64 @@ +name: Publish + +on: + push: + # Publish `v*` tags as releases. + tags: + - v* + pull_request: + +jobs: + publish: + runs-on: ubuntu-latest + if: github.event_name == 'push' + steps: + - + name: Checkout + uses: actions/checkout@v2 + - + name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: ${{ secrets.DOCKER_HUB_USERNAME }}/goldpinger + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - + name: Login to DockerHub + uses: docker/login-action@v1 + if: github.event_name != 'pull_request' + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + - + name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + context: . + file: ./Dockerfile + build-args: GO_MOD_ACTION=download + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + target: simple + - + name: Build and push vendor + id: docker_build_vendor + uses: docker/build-push-action@v2 + with: + context: . + flavor: | + suffix: -vendor,onlatest=false + file: ./Dockerfile + build-args: GO_MOD_ACTION=vendor + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + target: vendor diff --git a/Dockerfile b/Dockerfile index 2a04546..bbbf19f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,8 @@ -FROM golang:1.14-alpine as builder +FROM golang:1.15-alpine as builder +ARG TARGETARCH +ARG TARGETOS +ARG GO_MOD_ACTION=download +ENV GO111MODULE=on # Install our build tools @@ -8,16 +12,19 @@ RUN apk add --update git make bash WORKDIR /w COPY go.mod go.sum /w/ -RUN go mod download +RUN go mod $GO_MOD_ACTION # Build goldpinger COPY . ./ -RUN make bin/goldpinger +RUN GOOS=$TARGETOS GOARCH=$TARGETARCH make bin/goldpinger # Build the asset container, copy over goldpinger - -FROM scratch +FROM scratch as simple COPY --from=builder /w/bin/goldpinger /goldpinger COPY ./static /static ENTRYPOINT ["/goldpinger", "--static-file-path", "/static"] + +# For vendor builds, use the simple build and add the vendor'd files +FROM simple as vendor +COPY --from=builder /w/vendor /goldpinger-vendor-sources diff --git a/Makefile b/Makefile index ec63b44..df55e13 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,16 @@ name ?= goldpinger -version ?= v3.3.0 +version ?= v3.4.0 bin ?= goldpinger pkg ?= "github.com/bloomberg/goldpinger" tag = $(name):$(version) goos ?= ${GOOS} +goarch ?= ${GOARCH} namespace ?= "bloomberg/" files = $(shell find . -iname "*.go") bin/$(bin): $(files) - GOOS=${goos} PKG=${pkg} ARCH=amd64 VERSION=${version} BIN=${bin} ./build/build.sh + GOOS=${goos} PKG=${pkg} ARCH=${goarch} VERSION=${version} BIN=${bin} ./build/build.sh clean: rm -rf ./vendor @@ -24,34 +25,22 @@ swagger: swagger generate server -t pkg -f ./swagger.yml --exclude-main -A goldpinger && \ swagger generate client -t pkg -f ./swagger.yml -A goldpinger -build-multistage: - docker build -t $(tag) -f ./Dockerfile . +build-multistage: build -build: GOOS=linux -build: bin/$(bin) - docker build -t $(tag) -f ./build/Dockerfile-simple . +build-release: + docker buildx build --push --platform linux/amd64,linux/arm64 -t $(namespace)$(tag) --build-arg GO_MOD_ACTION=download --target simple -f ./Dockerfile . + docker buildx build --push --platform linux/amd64,linux/arm64 -t $(namespace)$(tag)-vendor --build-arg GO_MOD_ACTION=vendor --target vendor -f ./Dockerfile . -tag: - docker tag $(tag) $(namespace)$(tag) - -push: - docker push $(namespace)$(tag) +build: + docker build -t $(namespace)$(tag) --build-arg GO_MOD_ACTION=download --target simple -f ./Dockerfile . run: go run ./cmd/goldpinger/main.go version: - @echo $(tag) - + @echo $(namespace)$(tag) vendor-build: - docker build -t $(tag)-vendor --build-arg TAG=$(tag) -f ./build/Dockerfile-vendor . + docker build -t $(namespace)$(tag)-vendor --build-arg GO_MOD_ACTION=vendor --target vendor -f ./Dockerfile . -vendor-tag: - docker tag $(tag)-vendor $(namespace)$(tag)-vendor - -vendor-push: - docker push $(namespace)$(tag)-vendor - - -.PHONY: clean vendor swagger build build-multistage vendor-build vendor-tag vendor-push tag push run version +.PHONY: clean vendor swagger build build-multistage build-release vendor-build run version diff --git a/README.md b/README.md index 3276699..35b0787 100644 --- a/README.md +++ b/README.md @@ -68,21 +68,20 @@ The repo comes with two ways of building a `docker` image: compiling locally, an You will need `docker` version 17.05+ installed to support multi-stage builds. ```sh -# step 1: launch the build -make build-multistage +# Build a local container without publishing +make build -# step 2: push the image somewhere -namespace="docker.io/myhandle/" make tag -namespace="docker.io/myhandle/" make push +# Build & push the image somewhere +namespace="docker.io/myhandle/" make build-release ``` This was contributed via [@michiel](https://github.com/michiel) - kudos ! ### Compiling locally -In order to build `Goldpinger`, you are going to need `go` version 1.13+ and `docker`. +In order to build `Goldpinger`, you are going to need `go` version 1.15+ and `docker`. -Building from source code consists of compiling the binary and building a [Docker image](./build/Dockerfile-simple): +Building from source code consists of compiling the binary and building a [Docker image](./Dockerfile): ```sh # step 0: check out the code @@ -95,11 +94,10 @@ make bin/goldpinger ./bin/goldpinger --help # step 2: build the docker image containing the binary -make build +namespace="docker.io/myhandle/" make build # step 3: push the image somewhere -namespace="docker.io/myhandle/" make tag -namespace="docker.io/myhandle/" make push +docker push $(namespace="docker.io/myhandle/" make version) ``` ## Installation diff --git a/build/build.sh b/build/build.sh index 4ec1ded..5db382a 100755 --- a/build/build.sh +++ b/build/build.sh @@ -24,18 +24,14 @@ if [ -z "${PKG}" ]; then echo "PKG must be set" exit 1 fi -if [ -z "${ARCH}" ]; then - echo "ARCH must be set" - exit 1 -fi if [ -z "${VERSION}" ]; then echo "VERSION must be set" exit 1 fi export CGO_ENABLED=0 -export GOARCH="${ARCH}" -export GOOS=${GOOS:-} +export GOARCH="${ARCH:-amd64}" +export GOOS=${GOOS:-linux} go build \ -ldflags "-X 'main.Version=${VERSION}' -X 'main.Build=`date`'" \ diff --git a/docker_deploy.sh b/docker_deploy.sh index b1a33b9..3db729a 100755 --- a/docker_deploy.sh +++ b/docker_deploy.sh @@ -1,8 +1,4 @@ #!/bin/sh docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" \ - && make tag \ - && make push \ - && make vendor-tag \ - && make vendor-push - + && make build-release diff --git a/go.mod b/go.mod index 5976af3..0184b8e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/bloomberg/goldpinger/v3 -go 1.14 +go 1.15 require ( github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect