mirror of
https://github.com/goharbor/harbor.git
synced 2026-10-24 21:59:32 +03:00
The per-component base images (goharbor/harbor-core-base, harbor-db-base, harbor-portal-base, ...) were pushed by both BUILD_PACKAGE matrix jobs to the same unsuffixed tag (e.g. :dev), so whichever architecture finished last overwrote the other and the published tag ended up single-arch — the same last-writer-wins problem goharbor/photon:5.0 had before #23334 (#23324). Apply the same pattern already used for the component images: - make/photon/Makefile: _build_base keeps building the local unsuffixed tag (component Dockerfiles build FROM it unchanged) but pushes an arch-suffixed tag instead: harbor-<name>-base:<tag>-amd64 / -arm64. - .github/workflows/build-package.yml: each matrix job also saves the list of goharbor/*-base repos it built; CREATE_MANIFEST combines the two suffixed tags into the unsuffixed multi-arch manifest with docker buildx imagetools create, using the base tag scheme (dev on main, the release version on release-* branches). The base manifest step only runs when BUILD_BASE_IMAGE decided to rebuild bases, since otherwise no suffixed tags were pushed in this run. Consumers that pull harbor-*-base:<tag> (PULL_BASE_FROM_DOCKERHUB=true flows) now resolve the correct architecture via the manifest list instead of getting whatever architecture won the race. Signed-off-by: Vadim Bauer <vb@container-registry.com>
267 lines
13 KiB
Makefile
267 lines
13 KiB
Makefile
# Makefile for a harbor project
|
|
#
|
|
# Targets:
|
|
#
|
|
# build: build harbor photon images
|
|
# clean: clean core and jobservice harbor images
|
|
|
|
# common
|
|
SHELL := /bin/bash
|
|
BUILDPATH=$(CURDIR)
|
|
MAKEPATH=$(BUILDPATH)/make
|
|
SRCPATH=./src
|
|
TOOLSPATH=$(CURDIR)/tools
|
|
SEDCMD=$(shell which sed)
|
|
WGET=$(shell which wget)
|
|
CURL=$(shell which curl)
|
|
TIMESTAMP=$(shell date +"%Y%m%d")
|
|
PLATFORM = $(if $(filter $(ARCH),aarch64 arm64),linux/arm64,linux/amd64)
|
|
# Normalized Go architecture string (arm64/amd64), derived from ARCH.
|
|
# Used as --build-arg TARGETARCH to keep Go builds correct even when this
|
|
# sub-make is invoked directly with ARCH=aarch64 or ARCH=x86_64.
|
|
TARGETARCH = $(if $(filter $(ARCH),aarch64 arm64),arm64,amd64)
|
|
# Force BuildKit so --platform takes effect and TARGETARCH auto-populates.
|
|
# 'override' wins over the caller's environment even when the parent
|
|
# Makefile calls this sub-make with -e (environment-overrides).
|
|
override DOCKER_BUILDKIT := 1
|
|
export DOCKER_BUILDKIT
|
|
|
|
# docker parameters
|
|
DOCKERCMD=$(shell which docker)
|
|
DOCKERBUILD=$(DOCKERCMD) build --no-cache --network=$(DOCKERNETWORK) --platform=$(PLATFORM)
|
|
DOCKERBUILD_WITH_PULL_PARA=$(DOCKERBUILD) --pull=$(PULL_BASE_FROM_DOCKERHUB)
|
|
DOCKERRMIMAGE=$(DOCKERCMD) rmi
|
|
DOCKERIMAGES=$(DOCKERCMD) images
|
|
IMAGENAMESPACE=goharbor
|
|
BASEIMAGENAMESPACE=goharbor
|
|
|
|
# pushimage
|
|
PUSHSCRIPTPATH=$(MAKEPATH)
|
|
PUSHSCRIPTNAME=pushimage.sh
|
|
|
|
# binary
|
|
CORE_SOURCECODE=$(SRCPATH)/core
|
|
CORE_BINARYNAME=harbor_core
|
|
JOBSERVICESOURCECODE=$(SRCPATH)/jobservice
|
|
JOBSERVICEBINARYNAME=harbor_jobservice
|
|
|
|
# photon dockerfile
|
|
DOCKERFILEPATH=$(MAKEPATH)/photon
|
|
|
|
PREPARE=prepare
|
|
DOCKERFILEPATH_PREPARE=$(DOCKERFILEPATH)/$(PREPARE)
|
|
DOCKERFILENAME_PREPARE=Dockerfile
|
|
DOCKERIMAGENAME_PREPARE=$(IMAGENAMESPACE)/$(PREPARE)
|
|
|
|
PORTAL=portal
|
|
DOCKERFILEPATH_PORTAL=$(DOCKERFILEPATH)/$(PORTAL)
|
|
DOCKERFILENAME_PORTAL=Dockerfile
|
|
DOCKERIMAGENAME_PORTAL=$(IMAGENAMESPACE)/harbor-$(PORTAL)
|
|
|
|
CORE=core
|
|
DOCKERFILEPATH_CORE=$(DOCKERFILEPATH)/$(CORE)
|
|
DOCKERFILENAME_CORE=Dockerfile
|
|
DOCKERIMAGENAME_CORE=$(IMAGENAMESPACE)/harbor-$(CORE)
|
|
|
|
JOBSERVICE=jobservice
|
|
DOCKERFILEPATH_JOBSERVICE=$(DOCKERFILEPATH)/$(JOBSERVICE)
|
|
DOCKERFILENAME_JOBSERVICE=Dockerfile
|
|
DOCKERIMAGENAME_JOBSERVICE=$(IMAGENAMESPACE)/harbor-$(JOBSERVICE)
|
|
|
|
LOG=log
|
|
DOCKERFILEPATH_LOG=$(DOCKERFILEPATH)/$(LOG)
|
|
DOCKERFILENAME_LOG=Dockerfile
|
|
DOCKERIMAGENAME_LOG=$(IMAGENAMESPACE)/harbor-$(LOG)
|
|
|
|
DB=db
|
|
DOCKERFILEPATH_DB=$(DOCKERFILEPATH)/$(DB)
|
|
DOCKERFILENAME_DB=Dockerfile
|
|
DOCKERIMAGENAME_DB=$(IMAGENAMESPACE)/harbor-$(DB)
|
|
|
|
POSTGRESQL=postgresql
|
|
DOCKERFILEPATH_POSTGRESQL=$(DOCKERFILEPATH)/$(POSTGRESQL)
|
|
DOCKERFILENAME_POSTGRESQL=Dockerfile
|
|
DOCKERIMAGENAME_POSTGRESQL=$(IMAGENAMESPACE)/$(POSTGRESQL)-photon
|
|
|
|
TRIVY_ADAPTER=trivy-adapter
|
|
DOCKERFILEPATH_TRIVY_ADAPTER=$(DOCKERFILEPATH)/$(TRIVY_ADAPTER)
|
|
DOCKERFILENAME_TRIVY_ADAPTER=Dockerfile
|
|
DOCKERIMAGENAME_TRIVY_ADAPTER=$(IMAGENAMESPACE)/$(TRIVY_ADAPTER)-photon
|
|
|
|
NGINX=nginx
|
|
DOCKERFILEPATH_NGINX=$(DOCKERFILEPATH)/$(NGINX)
|
|
DOCKERFILENAME_NGINX=Dockerfile
|
|
DOCKERIMAGENAME_NGINX=$(IMAGENAMESPACE)/$(NGINX)-photon
|
|
|
|
REGISTRY=registry
|
|
DOCKERFILEPATH_REG=$(DOCKERFILEPATH)/$(REGISTRY)
|
|
DOCKERFILENAME_REG=Dockerfile
|
|
DOCKERIMAGENAME_REG=$(IMAGENAMESPACE)/$(REGISTRY)-photon
|
|
|
|
REGISTRYCTL=registryctl
|
|
DOCKERFILEPATH_REGISTRYCTL=$(DOCKERFILEPATH)/$(REGISTRYCTL)
|
|
DOCKERFILENAME_REGISTRYCTL=Dockerfile
|
|
DOCKERIMAGENAME_REGISTRYCTL=$(IMAGENAMESPACE)/harbor-$(REGISTRYCTL)
|
|
|
|
VALKEY=valkey
|
|
DOCKERFILEPATH_VALKEY=$(DOCKERFILEPATH)/$(VALKEY)
|
|
DOCKERFILENAME_VALKEY=Dockerfile
|
|
DOCKERIMAGENAME_VALKEY=$(IMAGENAMESPACE)/$(VALKEY)-photon
|
|
|
|
DOCKERFILEPATH_STANDALONE_DB_MIGRATOR=$(DOCKERFILEPATH)/standalone-db-migrator
|
|
DOCKERFILENAME_STANDALONE_DB_MIGRATOR=Dockerfile
|
|
DOCKERIMAGENAME_STANDALONE_DB_MIGRATOR=$(IMAGENAMESPACE)/standalone-db-migrator
|
|
|
|
EXPORTER=exporter
|
|
DOCKERFILEPATH_EXPORTER=$(DOCKERFILEPATH)/$(EXPORTER)
|
|
DOCKERFILENAME_EXPORTER=Dockerfile
|
|
DOCKERIMAGENAME_EXPORTER=$(IMAGENAMESPACE)/harbor-$(EXPORTER)
|
|
|
|
_build_prepare:
|
|
@$(call _build_base,$(PREPARE),$(DOCKERFILEPATH_PREPARE))
|
|
@echo "building prepare container for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) --build-arg pip_index_url=$(PIP_INDEX_URL) -f $(DOCKERFILEPATH_PREPARE)/$(DOCKERFILENAME_PREPARE) -t $(DOCKERIMAGENAME_PREPARE):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_db:
|
|
@$(call _build_base,$(DB),$(DOCKERFILEPATH_DB))
|
|
@echo "building db container for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_DB)/$(DOCKERFILENAME_DB) -t $(DOCKERIMAGENAME_DB):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_portal:
|
|
@$(call _build_base,$(PORTAL),$(DOCKERFILEPATH_PORTAL))
|
|
@echo "building portal container for photon..."
|
|
$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) --build-arg NODE=${NODEBUILDIMAGE} --build-arg npm_registry=$(NPM_REGISTRY) -f $(DOCKERFILEPATH_PORTAL)/$(DOCKERFILENAME_PORTAL) -t $(DOCKERIMAGENAME_PORTAL):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_core:
|
|
@$(call _build_base,$(CORE),$(DOCKERFILEPATH_CORE))
|
|
@echo "building core container for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_CORE)/$(DOCKERFILENAME_CORE) -t $(DOCKERIMAGENAME_CORE):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_jobservice:
|
|
@$(call _build_base,$(JOBSERVICE),$(DOCKERFILEPATH_JOBSERVICE))
|
|
@echo "building jobservice container for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_JOBSERVICE)/$(DOCKERFILENAME_JOBSERVICE) -t $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_log:
|
|
@$(call _build_base,$(LOG),$(DOCKERFILEPATH_LOG))
|
|
@echo "building log container for photon..."
|
|
$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_LOG)/$(DOCKERFILENAME_LOG) -t $(DOCKERIMAGENAME_LOG):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_trivy_adapter:
|
|
@if [ "$(TRIVYFLAG)" = "true" ] ; then \
|
|
$(call _build_base,$(TRIVY_ADAPTER),$(DOCKERFILEPATH_TRIVY_ADAPTER)) ; \
|
|
rm -rf $(DOCKERFILEPATH_TRIVY_ADAPTER)/binary && mkdir -p $(DOCKERFILEPATH_TRIVY_ADAPTER)/binary ; \
|
|
echo "Downloading Trivy scanner $(TRIVYVERSION)..." ; \
|
|
$(call _extract_archive, $(TRIVY_DOWNLOAD_URL), $(DOCKERFILEPATH_TRIVY_ADAPTER)/binary/) ; \
|
|
if [ "$(BUILDTRIVYADP)" != "true" ] ; then \
|
|
echo "Downloading Trivy adapter $(TRIVYADAPTERVERSION)..." ; \
|
|
$(call _extract_archive, $(TRIVY_ADAPTER_DOWNLOAD_URL), $(DOCKERFILEPATH_TRIVY_ADAPTER)/binary/) ; \
|
|
else \
|
|
echo "Building Trivy adapter $(TRIVYADAPTERVERSION) from sources..." ; \
|
|
cd $(DOCKERFILEPATH_TRIVY_ADAPTER) && $(DOCKERFILEPATH_TRIVY_ADAPTER)/builder.sh $(TRIVYADAPTERVERSION) $(GOBUILDIMAGE) $(DOCKERNETWORK) && cd - ; \
|
|
fi ; \
|
|
echo "Building Trivy adapter container for photon..." ; \
|
|
$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) \
|
|
--build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) \
|
|
--build-arg trivy_version=$(TRIVYVERSION) \
|
|
-f $(DOCKERFILEPATH_TRIVY_ADAPTER)/$(DOCKERFILENAME_TRIVY_ADAPTER) \
|
|
-t $(DOCKERIMAGENAME_TRIVY_ADAPTER):$(VERSIONTAG) . ; \
|
|
rm -rf $(DOCKERFILEPATH_TRIVY_ADAPTER)/binary; \
|
|
echo "Done." ; \
|
|
fi
|
|
|
|
_build_nginx:
|
|
@$(call _build_base,$(NGINX),$(DOCKERFILEPATH_NGINX))
|
|
@echo "building nginx container for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_NGINX)/$(DOCKERFILENAME_NGINX) -t $(DOCKERIMAGENAME_NGINX):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_registry:
|
|
@$(call _build_base,$(REGISTRY),$(DOCKERFILEPATH_REG))
|
|
@if [ "$(BUILDREG)" != "true" ] ; then \
|
|
rm -rf $(DOCKERFILEPATH_REG)/binary && mkdir -p $(DOCKERFILEPATH_REG)/binary && \
|
|
$(call _get_binary, $(REGISTRYURL), $(DOCKERFILEPATH_REG)/binary/registry); \
|
|
else \
|
|
cd $(DOCKERFILEPATH_REG) && $(DOCKERFILEPATH_REG)/builder $(REGISTRY_SRC_TAG) $(DISTRIBUTION_SRC) $(GOBUILDIMAGE) $(DOCKERNETWORK) && cd - ; \
|
|
fi
|
|
@echo "building registry container for photon..."
|
|
@chmod 655 $(DOCKERFILEPATH_REG)/binary/registry && $(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_REG)/$(DOCKERFILENAME_REG) -t $(DOCKERIMAGENAME_REG):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_registryctl:
|
|
@$(call _build_base,$(REGISTRYCTL),$(DOCKERFILEPATH_REGISTRYCTL))
|
|
@echo "building registry controller for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_REGISTRYCTL)/$(DOCKERFILENAME_REGISTRYCTL) -t $(DOCKERIMAGENAME_REGISTRYCTL):$(VERSIONTAG) .
|
|
@rm -rf $(DOCKERFILEPATH_REG)/binary
|
|
@echo "Done."
|
|
|
|
_build_valkey:
|
|
@$(call _build_base,$(VALKEY),$(DOCKERFILEPATH_VALKEY),--build-arg VALKEY_VERSION=$(VALKEYVERSION) --build-arg VALKEY_SHA256=$(VALKEYSHA256))
|
|
@echo "building valkey container for photon..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_VALKEY)/$(DOCKERFILENAME_VALKEY) -t $(DOCKERIMAGENAME_VALKEY):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_build_standalone_db_migrator:
|
|
@echo "building standalone db migrator image for photon..."
|
|
$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_STANDALONE_DB_MIGRATOR)/$(DOCKERFILENAME_STANDALONE_DB_MIGRATOR) -t $(DOCKERIMAGENAME_STANDALONE_DB_MIGRATOR):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
_compile_and_build_exporter:
|
|
@$(call _build_base,$(EXPORTER),$(DOCKERFILEPATH_EXPORTER))
|
|
@echo "compiling and building image for exporter..."
|
|
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) --build-arg build_image=$(GOBUILDIMAGE) --build-arg harbor_version=$(RELEASEVERSION) --build-arg git_commit=$(GITCOMMIT) --build-arg TARGETARCH=$(TARGETARCH) -f ${DOCKERFILEPATH_EXPORTER}/${DOCKERFILENAME_EXPORTER} -t $(DOCKERIMAGENAME_EXPORTER):$(VERSIONTAG) .
|
|
@echo "Done."
|
|
|
|
define _extract_archive
|
|
echo "download $1";\
|
|
$(CURL) --connect-timeout 30 -f -k -L $1 | tar xvz -C $2 || exit 1
|
|
endef
|
|
|
|
define _get_binary
|
|
echo "download $1";\
|
|
$(CURL) --connect-timeout 30 -f -k -L $1 -o $2 || exit 1
|
|
endef
|
|
|
|
define _build_base
|
|
if [ "$(BUILD_BASE)" = "true" ] ; then \
|
|
echo "building base image for $(1)...";\
|
|
if [ -n "$(REGISTRYUSER)" ] && [ -n "$(REGISTRYPASSWORD)" ] ; then \
|
|
docker login -u $(REGISTRYUSER) -p $(REGISTRYPASSWORD) ; \
|
|
else \
|
|
echo "No docker credentials provided, please be aware of privileges to access docker hub!" ; \
|
|
fi ;\
|
|
$(DOCKERBUILD) -f $(2)/Dockerfile.base --build-arg pip_index_url=$(PIP_INDEX_URL) --build-arg TARGETARCH=$(TARGETARCH) $(3) -t $(BASEIMAGENAMESPACE)/harbor-$(1)-base:$(BASEIMAGETAG) --label base-build-date=$(TIMESTAMP) . ;\
|
|
if [ "$(PUSHBASEIMAGE)" = "true" ] ; then \
|
|
$(DOCKERCMD) tag $(BASEIMAGENAMESPACE)/harbor-$(1)-base:$(BASEIMAGETAG) $(BASEIMAGENAMESPACE)/harbor-$(1)-base:$(BASEIMAGETAG)-$(TARGETARCH) ; \
|
|
$(PUSHSCRIPTPATH)/$(PUSHSCRIPTNAME) $(BASEIMAGENAMESPACE)/harbor-$(1)-base:$(BASEIMAGETAG)-$(TARGETARCH) $(REGISTRYUSER) $(REGISTRYPASSWORD) docker.io $(PULL_BASE_FROM_DOCKERHUB) || exit 1; \
|
|
fi ; \
|
|
fi
|
|
endef
|
|
|
|
ifeq ($(BUILD_INSTALLER), true)
|
|
buildcompt: _build_prepare _build_db _build_portal _build_core _build_jobservice _build_log _build_nginx _build_registry _build_registryctl _build_trivy_adapter _build_valkey _compile_and_build_exporter
|
|
else
|
|
buildcompt: _build_db _build_portal _build_core _build_jobservice _build_nginx _build_registry _build_registryctl _build_trivy_adapter _build_valkey _compile_and_build_exporter
|
|
endif
|
|
|
|
build: buildcompt
|
|
@if [ -n "$(REGISTRYUSER)" ] && [ -n "$(REGISTRYPASSWORD)" ] ; then \
|
|
docker logout ; \
|
|
fi
|
|
|
|
cleanimage:
|
|
@echo "cleaning image for photon..."
|
|
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_PORTAL):$(VERSIONTAG)
|
|
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_CORE):$(VERSIONTAG)
|
|
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG)
|
|
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_LOG):$(VERSIONTAG)
|
|
|
|
.PHONY: clean
|
|
clean: cleanimage
|