From 8d1f3d290b5303cd35773ea11fc03795aa03e1c1 Mon Sep 17 00:00:00 2001 From: Jerome Touffe-Blin Date: Sat, 25 Nov 2023 12:03:40 +1100 Subject: [PATCH] Build docker cross-platform with buildx --- .circleci/config.yml | 48 ++++++++++++++++++++++++++++++++++++++++++++ Makefile | 33 +++++++++++++++++++----------- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7fca8db..0e554df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,6 +31,43 @@ jobs: - run: name: "build and test" command: make build test-race check bench-race coveralls + build-docker: + docker: # executor type + - image: cimg/base:stable # primary container will run the latest, production-ready base image + auth: + username: $DOCKERHUB_USERNAME + password: $DOCKERHUB_PASSWORD + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Docker build + command: | + make docker-ci + release: + docker: # executor type + - image: cimg/base:stable # primary container will run the latest, production-ready base image + auth: + username: $DOCKERHUB_USERNAME + password: $DOCKERHUB_PASSWORD + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Docker push + command: | + if [ ! -z "$CIRCLE_TAG" ]; then + echo "Executing release on tag build $CIRCLE_TAG"; + if [ "$CIRCLE_TAG" = "dev" ]; then + make docker-dev + else + make release-ci + fi + else + echo "Not executing release on non-tag build"; + fi # Orchestrate jobs using workflows # See: https://circleci.com/docs/configuration-reference/#workflows @@ -38,3 +75,14 @@ workflows: kube2iam-workflow: jobs: - build-and-test + - build-docker + - release: + requires: + - build-and-test + - build-docker + filters: + branches: + only: + - main + - /release-[\w\.]+/ + diff --git a/Makefile b/Makefile index 706ee16..01d01e0 100644 --- a/Makefile +++ b/Makefile @@ -10,13 +10,14 @@ GIT_HASH := $$(git rev-parse --short HEAD) GOBUILD_VERSION_ARGS := -ldflags "-s -X $(VERSION_VAR)=$(REPO_VERSION) -X $(GIT_VAR)=$(GIT_HASH) -X $(BUILD_DATE_VAR)=$(BUILD_DATE)" # useful for other docker repos DOCKER_REPO ?= jtblin -CPU_ARCH ?= amd64 +CPU_ARCH ?= arm64 IMAGE_NAME := $(DOCKER_REPO)/$(BINARY_NAME)-$(CPU_ARCH) MANIFEST_NAME := $(DOCKER_REPO)/$(BINARY_NAME) ARCH ?= darwin GOLANGCI_LINT_VERSION ?= v1.23.8 GOLANGCI_LINT_CONCURRENCY ?= 4 GOLANGCI_LINT_DEADLINE ?= 180 +PLATFORMS ?= linux/arm/v7,linux/arm64/v8,linux/amd64 # useful for passing --build-arg http_proxy :) DOCKER_BUILD_FLAGS := @@ -72,7 +73,11 @@ check-all: golangci-lint run --enable=gocyclo --concurrency=$(GOLANGCI_LINT_CONCURRENCY) --deadline=600s docker: - docker build -t $(IMAGE_NAME):$(GIT_HASH) . $(DOCKER_BUILD_FLAGS) + docker buildx create --name multiarch --use + docker buildx build --platform $(PLATFORMS) -t $(IMAGE_NAME):$(GIT_HASH) . $(DOCKER_BUILD_FLAGS) + +docker-ci: docker + docker push $(IMAGE_NAME):$(GIT_HASH) docker-dev: docker docker tag $(IMAGE_NAME):$(GIT_HASH) $(IMAGE_NAME):dev @@ -87,20 +92,24 @@ ifeq (, $(findstring -rc, $(REPO_VERSION))) docker push $(IMAGE_NAME):latest endif -release-manifest: - for tag in latest $(REPO_VERSION); do \ - for arch in amd64 arm64; do \ - docker pull $(MANIFEST_NAME)-$$arch:$$tag; \ - done; \ - docker manifest create $(MANIFEST_NAME):$$tag --amend \ - $(MANIFEST_NAME)-amd64:$$tag \ - $(MANIFEST_NAME)-arm64:$$tag; \ - docker manifest push $(MANIFEST_NAME):$$tag; \ - done +release-ci: + docker tag $(IMAGE_NAME):$(GIT_HASH) $(IMAGE_NAME):$(REPO_VERSION) + docker push $(IMAGE_NAME):$(REPO_VERSION) +ifeq (, $(findstring -rc, $(REPO_VERSION))) + docker tag $(IMAGE_NAME):$(GIT_HASH) $(IMAGE_NAME):latest + docker push $(IMAGE_NAME):latest +endif version: @echo $(REPO_VERSION) +info-release: + @echo IMAGE_NAME=$(IMAGE_NAME) + @echo GIT_HASH=$(GIT_HASH) + @echo REPO_VERSION=$(REPO_VERSION) + @echo MANIFEST_NAME=$(MANIFEST_NAME) + @echo PLATFORMS=$(PLATFORMS) + clean: rm -rf build/bin/*