You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@inlong.apache.org by do...@apache.org on 2022/07/07 07:50:00 UTC

[inlong] branch master updated: [INLONG-4862][Docker] Add publish images by arch and push manifest script (#4863)

This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git


The following commit(s) were added to refs/heads/master by this push:
     new f851189fb [INLONG-4862][Docker] Add publish images by arch and push manifest script (#4863)
f851189fb is described below

commit f851189fb4b006182915409200a969c5339a2e98
Author: Lucas <10...@users.noreply.github.com>
AuthorDate: Thu Jul 7 15:49:55 2022 +0800

    [INLONG-4862][Docker] Add publish images by arch and push manifest script (#4863)
---
 .github/labeler.yml               |   2 +
 .github/workflows/ci_docker.yml   |  28 +++-
 docker/build-arm-docker-images.sh |  74 ---------
 docker/build-docker-images.sh     | 144 ++++++++++++++++++
 docker/publish-by-arch.sh         | 310 ++++++++++++++++++++++++++++++++++++++
 docker/publish.sh                 |  96 ------------
 6 files changed, 482 insertions(+), 172 deletions(-)

diff --git a/.github/labeler.yml b/.github/labeler.yml
index 161054015..4a7342a8c 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -55,6 +55,8 @@ docker:
   - 'inlong-manager/manager-docker/**/*'
   - 'inlong-tubemq/tubemq-docker/**/*'
   - 'docker/docker-compose/**/*'
+  - 'docker/build-docker-images.sh'
+  - 'docker/publish-by-arch.sh'
 
 k8s:
   - '.github/ct.yml'
diff --git a/.github/workflows/ci_docker.yml b/.github/workflows/ci_docker.yml
index 5fd91a36a..7bf96bd00 100644
--- a/.github/workflows/ci_docker.yml
+++ b/.github/workflows/ci_docker.yml
@@ -99,13 +99,37 @@ jobs:
           fi
 
       # If only this workflow file is changed, there is no need to publish Docker images.
-      - name: Push Docker images to Docker Hub
+      - name: Push x86 Docker images to Docker Hub
         if: |
           success()
           && steps.check-workflow-diff.outputs.changed_only == 'no'
           && steps.match-branch.outputs.match == 'true'
         working-directory: docker
-        run: bash +x publish.sh
+        run: bash +x publish-by-arch.sh --tag --publish
+        env:
+          DOCKER_USER: ${{ secrets.DOCKER_USER }}
+          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
+
+      # If only this workflow file is changed, there is no need to publish Docker images.
+      - name: Push aarch64 Docker images to Docker Hub
+        if: |
+          success()
+          && steps.check-workflow-diff.outputs.changed_only == 'no'
+          && steps.match-branch.outputs.match == 'true'
+        working-directory: docker
+        run: bash +x publish-by-arch.sh --tag --buildx aarch64 --publish
+        env:
+          DOCKER_USER: ${{ secrets.DOCKER_USER }}
+          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
+
+      # If only this workflow file is changed, there is no need to publish Docker images.
+      - name: Push manifest to Docker Hub
+        if: |
+          success()
+          && steps.check-workflow-diff.outputs.changed_only == 'no'
+          && steps.match-branch.outputs.match == 'true'
+        working-directory: docker
+        run: bash +x publish-by-arch.sh --manifest
         env:
           DOCKER_USER: ${{ secrets.DOCKER_USER }}
           DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
diff --git a/docker/build-arm-docker-images.sh b/docker/build-arm-docker-images.sh
deleted file mode 100644
index 453405bd4..000000000
--- a/docker/build-arm-docker-images.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
-
-cd ${SHELL_FOLDER}
-cd ..
-mvn clean install -DskipTests
-
-version=`awk '/<version>[^<]+<\/version>/{i++}i==2{gsub(/<version>|<\/version>/,"",$1);print $0;exit;}' pom.xml`
-tag=${version}-aarch64
-
-manager_dockerfile_path="inlong-manager/manager-docker/"
-agent_dockerfile_path="inlong-agent/agent-docker/"
-audit_dockerfile_path="inlong-audit/audit-docker/"
-dataproxy_dockerfile_path="inlong-dataproxy/dataproxy-docker/"
-tubemq_manager_dockerfile_path="inlong-tubemq/tubemq-docker/tubemq-manager/"
-
-manager_tarball_name="apache-inlong-manager-web-${version}-bin.tar.gz"
-agent_tarball_name="apache-inlong-agent-${version}-bin.tar.gz"
-audit_tarball_name="apache-inlong-audit-${version}-bin.tar.gz"
-dataproxy_tarball_name="apache-inlong-dataproxy-${version}-bin.tar.gz"
-dashboard_file_name="build"
-tubemq_manager_tarball_name="apache-inlong-tubemq-manager-${version}-bin.tar.gz"
-
-manager_tarball="inlong-manager/manager-web/target/${manager_tarball_name}"
-agent_tarball="inlong-agent/agent-release/target/${agent_tarball_name}"
-audit_tarball="inlong-audit/audit-release/target/${audit_tarball_name}"
-dataproxy_tarball="inlong-dataproxy/dataproxy-dist/target/${dataproxy_tarball_name}"
-tubemq_manager_tarball="inlong-tubemq/tubemq-manager/target/${tubemq_manager_tarball_name}"
-
-MANAGER_TARBALL="target/${manager_tarball_name}"
-DATAPROXY_TARBALL="target/${dataproxy_tarball_name}"
-AUDIT_TARBALL="target/${audit_tarball_name}"
-TUBEMQ_MANAGER_TARBALL="target/${tubemq_manager_tarball_name}"
-DASHBOARD_FILE="${dashboard_file_name}"
-AGENT_TARBALL="target/${agent_tarball_name}"
-
-cp ${manager_tarball} ${manager_dockerfile_path}/target/${manager_tarball_name}
-cp ${agent_tarball} ${agent_dockerfile_path}/target/${agent_tarball_name}
-cp ${audit_tarball} ${audit_dockerfile_path}/target/${audit_tarball_name}
-cp ${dataproxy_tarball} ${dataproxy_dockerfile_path}/target/${dataproxy_tarball_name}
-cp ${tubemq_manager_tarball} ${tubemq_manager_dockerfile_path}/target/${tubemq_manager_tarball_name}
-
-docker build -t inlong/manager:${tag} inlong-manager/manager-docker/ --build-arg MANAGER_TARBALL=${MANAGER_TARBALL}
-docker build -t inlong/dataproxy:${tag} inlong-dataproxy/dataproxy-docker/ --build-arg DATAPROXY_TARBALL=${DATAPROXY_TARBALL}
-docker build -t inlong/audit:${tag} inlong-audit/audit-docker/ --build-arg AUDIT_TARBALL=${AUDIT_TARBALL}
-docker build -t inlong/tubemq-manager:${tag} inlong-tubemq/tubemq-docker/tubemq-manager/ --build-arg TUBEMQ_MANAGER_TARBALL=${TUBEMQ_MANAGER_TARBALL}
-docker build -t inlong/dashboard:${tag} inlong-dashboard/ --build-arg DASHBOARD_FILE=${DASHBOARD_FILE}
-docker build -t inlong/agent:${tag} inlong-agent/agent-docker/ --build-arg AGENT_TARBALL=${AGENT_TARBALL}
-
-docker tag inlong/manager:${tag} inlong/manager:latest-aarch64
-docker tag inlong/dataproxy:${tag} inlong/dataproxy:latest-aarch64
-docker tag inlong/audit:${tag} inlong/audit:latest-aarch64
-docker tag inlong/tubemq-manager:${tag} inlong/tubemq-manager:latest-aarch64
-docker tag inlong/dashboard:${tag} inlong/dashboard:latest-aarch64
-docker tag inlong/agent:${tag} inlong/agent:latest-aarch64
diff --git a/docker/build-docker-images.sh b/docker/build-docker-images.sh
new file mode 100644
index 000000000..11fc388c3
--- /dev/null
+++ b/docker/build-docker-images.sh
@@ -0,0 +1,144 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+ARCH_X86="x86"
+ARCH_AARCH64="aarch64"
+ENV_ARCH=$(uname -m)
+BUILD_ARCH="aarch64"
+POSTFIX="-aarch64"
+
+PLATFORM_AARCH64="--platform linux/arm64/v8"
+PLATFORM_X86="--platform linux/amd64"
+USE_PLATFORM=""
+
+SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
+
+cd ${SHELL_FOLDER}
+cd ..
+
+USE_BUILDX=""
+
+helpFunc() {
+  cat <<EOF
+Usage: ./build-arm-docker-images.sh [option]
+Options:
+  No option              Default build arm images on aarch64 environment.
+  -x, --buildx <ARCH>    Use buildx to build docker images for another arch.
+  -h, --help             Show help information.
+Example:
+  Use "./build-arm-docker-images.sh" to build arm images on aarch64 environment.
+  Use "./build-arm-docker-images.sh --buildx" to build arm images with buildx.
+EOF
+}
+
+for (( i=1; i<=$#; i++)); do
+  if [ "${!i}" = "-x" ] || [ "${!i}" = "--buildx" ]; then
+    NEED_BUILD=true
+    USE_BUILDX="buildx"
+    j=$((i+1))
+    BUILD_ARCH=${!j}
+    if [ "$BUILD_ARCH" != "$ARCH_AARCH64" ] && [ "$BUILD_ARCH" != "$ARCH_X86" ]; then
+      echo "Wrong arch name: ${BUILD_ARCH}. Please input aarch64 or x86."
+      exit 1
+    fi
+    shift
+  elif [ "${!i}" = "-h" ] || [ "${!i}" = "--help" ]; then
+    helpFunc
+    exit 0
+  else
+    echo "Wrong param: ${!i}. Please check help information."
+    helpFunc
+    exit 1
+  fi
+done
+
+if [ "$BUILD_ARCH" = "$ARCH_X86" ] && [ "$ENV_ARCH" = "$ARCH_X86" ]; then
+  mvn clean install -DskipTests -Pdocker
+  exit 0
+fi
+
+version=`awk '/<version>[^<]+<\/version>/{i++}i==2{gsub(/<version>|<\/version>/,"",$1);print $0;exit;}' pom.xml`
+tag=${version}-aarch64
+if [ "$BUILD_ARCH" = "$ARCH_X86" ]; then
+  tag=${version}-x86
+  POSTFIX="-x86"
+fi
+
+manager_dockerfile_path="inlong-manager/manager-docker/"
+agent_dockerfile_path="inlong-agent/agent-docker/"
+audit_dockerfile_path="inlong-audit/audit-docker/"
+dataproxy_dockerfile_path="inlong-dataproxy/dataproxy-docker/"
+tubemq_manager_dockerfile_path="inlong-tubemq/tubemq-docker/tubemq-manager/"
+tubemq_all_dockerfile_path="inlong-tubemq/tubemq-docker/tubemq-all/"
+
+manager_tarball_name="apache-inlong-manager-web-${version}-bin.tar.gz"
+agent_tarball_name="apache-inlong-agent-${version}-bin.tar.gz"
+audit_tarball_name="apache-inlong-audit-${version}-bin.tar.gz"
+dataproxy_tarball_name="apache-inlong-dataproxy-${version}-bin.tar.gz"
+dashboard_file_name="build"
+tubemq_manager_tarball_name="apache-inlong-tubemq-manager-${version}-bin.tar.gz"
+tubemq_all_tarball_name="apache-inlong-tubemq-server-${version}-bin.tar.gz"
+
+manager_tarball="inlong-manager/manager-web/target/${manager_tarball_name}"
+agent_tarball="inlong-agent/agent-release/target/${agent_tarball_name}"
+audit_tarball="inlong-audit/audit-release/target/${audit_tarball_name}"
+dataproxy_tarball="inlong-dataproxy/dataproxy-dist/target/${dataproxy_tarball_name}"
+tubemq_manager_tarball="inlong-tubemq/tubemq-manager/target/${tubemq_manager_tarball_name}"
+tubemq_all_tarball="inlong-tubemq/tubemq-server/target/${tubemq_all_tarball_name}"
+
+MANAGER_TARBALL="target/${manager_tarball_name}"
+DATAPROXY_TARBALL="target/${dataproxy_tarball_name}"
+AUDIT_TARBALL="target/${audit_tarball_name}"
+TUBEMQ_MANAGER_TARBALL="target/${tubemq_manager_tarball_name}"
+DASHBOARD_FILE="${dashboard_file_name}"
+AGENT_TARBALL="target/${agent_tarball_name}"
+TUBEMQ_TARBALL="target/${tubemq_all_tarball_name}"
+
+cp ${manager_tarball} ${manager_dockerfile_path}/target/${manager_tarball_name}
+cp ${agent_tarball} ${agent_dockerfile_path}/target/${agent_tarball_name}
+cp ${audit_tarball} ${audit_dockerfile_path}/target/${audit_tarball_name}
+cp ${dataproxy_tarball} ${dataproxy_dockerfile_path}/target/${dataproxy_tarball_name}
+cp ${tubemq_manager_tarball} ${tubemq_manager_dockerfile_path}/target/${tubemq_manager_tarball_name}
+if [ "$BUILD_ARCH" = "$ARCH_X86" ]; then
+  cp ${tubemq_all_tarball} ${tubemq_all_dockerfile_path}/target/${tubemq_all_tarball_name}
+fi
+
+docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/manager:${tag}        inlong-manager/manager-docker/      --build-arg MANAGER_TARBALL=${MANAGER_TARBALL}
+docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/dataproxy:${tag}      inlong-dataproxy/dataproxy-docker/  --build-arg DATAPROXY_TARBALL=${DATAPROXY_TARBALL}
+docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/audit:${tag}          inlong-audit/audit-docker/          --build-arg AUDIT_TARBALL=${AUDIT_TARBALL}
+docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/tubemq-manager:${tag} inlong-tubemq/tubemq-docker/tubemq-manager/ --build-arg TUBEMQ_MANAGER_TARBALL=${TUBEMQ_MANAGER_TARBALL}
+docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/dashboard:${tag}      inlong-dashboard/                   --build-arg DASHBOARD_FILE=${DASHBOARD_FILE}
+docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/agent:${tag}          inlong-agent/agent-docker/          --build-arg AGENT_TARBALL=${AGENT_TARBALL}
+if [ "$BUILD_ARCH" = "$ARCH_X86" ]; then
+  docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/tubemq-all:${tag}    inlong-tubemq/tubemq-docker/tubemq-all/ --build-arg TUBEMQ_TARBALL=${TUBEMQ_TARBALL}
+  docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/tubemq-cpp:${tag}    inlong-tubemq/tubemq-docker/tubemq-cpp/
+  docker ${USE_BUILDX} build ${USE_PLATFORM} -t inlong/tubemq-build:${tag}  inlong-tubemq/tubemq-docker/tubemq-build/
+fi
+
+docker tag inlong/manager:${tag}         inlong/manager:latest${POSTFIX}
+docker tag inlong/dataproxy:${tag}       inlong/dataproxy:latest${POSTFIX}
+docker tag inlong/audit:${tag}           inlong/audit:latest${POSTFIX}
+docker tag inlong/tubemq-manager:${tag}  inlong/tubemq-manager:latest${POSTFIX}
+docker tag inlong/dashboard:${tag}       inlong/dashboard:latest${POSTFIX}
+docker tag inlong/agent:${tag}           inlong/agent:latest${POSTFIX}
+if [ "$BUILD_ARCH" = "$ARCH_X86" ]; then
+  docker tag inlong/tubemq-cpp:${tag}   inlong/tubemq-cpp:latest${POSTFIX}
+  docker tag inlong/tubemq-build:${tag} inlong/tubemq-build:latest${POSTFIX}
+  docker tag inlong/tubemq-all:${tag}   inlong/tubemq-all:latest${POSTFIX}
+fi
diff --git a/docker/publish-by-arch.sh b/docker/publish-by-arch.sh
new file mode 100644
index 000000000..a17952b80
--- /dev/null
+++ b/docker/publish-by-arch.sh
@@ -0,0 +1,310 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+ARCH_X86="x86"
+ARCH_AARCH64="aarch64"
+ENV_ARCH=$(uname -m)
+BUILD_ARCH=""
+
+NEED_BUILD=false
+NEED_TAG=false
+NEED_PUBLISH=false
+NEED_MANIFEST=false
+USE_BUILDX=""
+
+SRC_POSTFIX=""
+DES_POSTFIX="-x86"
+
+SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
+MVN_VERSION=$(python ${SHELL_FOLDER}/get-project-version.py)
+
+buildImage() {
+  echo "Start building images"
+  cd "${SHELL_FOLDER}"
+  cd ..
+  if [ "$BUILD_ARCH" = "$ARCH_X86" ] && [ "$ENV_ARCH" = "$ARCH_X86" ]; then
+    mvn clean install -DskipTests -Pdocker
+  else
+    mvn clean install -DskipTests
+    sh ./docker/build-docker-images.sh ${USE_BUILDX} ${BUILD_ARCH}
+  fi
+  echo "End building images"
+}
+
+initTagImageForx86() {
+  SRC_POSTFIX=""
+  DES_POSTFIX="-x86"
+  docker tag inlong/manager:latest${SRC_POSTFIX}         inlong/manager:latest${DES_POSTFIX}
+  docker tag inlong/agent:latest${SRC_POSTFIX}           inlong/agent:latest${DES_POSTFIX}
+  docker tag inlong/dataproxy:latest${SRC_POSTFIX}       inlong/dataproxy:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-manager:latest${SRC_POSTFIX}  inlong/tubemq-manager:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-all:latest${SRC_POSTFIX}      inlong/tubemq-all:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-build:latest${SRC_POSTFIX}    inlong/tubemq-build:latest${DES_POSTFIX}
+  docker tag inlong/dashboard:latest${SRC_POSTFIX}       inlong/dashboard:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-cpp:latest${SRC_POSTFIX}      inlong/tubemq-cpp:latest${DES_POSTFIX}
+  docker tag inlong/audit:latest${SRC_POSTFIX}           inlong/audit:latest${DES_POSTFIX}
+
+  docker tag inlong/manager:${MVN_VERSION}${SRC_POSTFIX}         inlong/manager:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/agent:${MVN_VERSION}${SRC_POSTFIX}           inlong/agent:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/dataproxy:${MVN_VERSION}${SRC_POSTFIX}       inlong/dataproxy:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-manager:${MVN_VERSION}${SRC_POSTFIX}  inlong/tubemq-manager:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-all:${MVN_VERSION}${SRC_POSTFIX}      inlong/tubemq-all:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-build:${MVN_VERSION}${SRC_POSTFIX}    inlong/tubemq-build:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/dashboard:${MVN_VERSION}${SRC_POSTFIX}       inlong/dashboard:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-cpp:${MVN_VERSION}${SRC_POSTFIX}      inlong/tubemq-cpp:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/audit:${MVN_VERSION}${SRC_POSTFIX}           inlong/audit:${MVN_VERSION}${DES_POSTFIX}
+}
+
+tagImage() {
+  if [[ -z ${DOCKER_REGISTRY} ]]; then
+    docker_registry_org=${DOCKER_ORG}
+  else
+    docker_registry_org=${DOCKER_REGISTRY}/${DOCKER_ORG}
+  fi
+  echo "Start tagging images"
+
+  if [ "$BUILD_ARCH" = "$ARCH_AARCH64" ]; then
+    SRC_POSTFIX="-aarch64"
+    DES_POSTFIX="-aarch64"
+  else
+    initTagImageForx86
+    SRC_POSTFIX="-x86"
+    DES_POSTFIX="-x86"
+  fi
+
+  docker tag inlong/manager:latest${SRC_POSTFIX}         ${docker_registry_org}/manager:latest${DES_POSTFIX}
+  docker tag inlong/agent:latest${SRC_POSTFIX}           ${docker_registry_org}/agent:latest${DES_POSTFIX}
+  docker tag inlong/dataproxy:latest${SRC_POSTFIX}       ${docker_registry_org}/dataproxy:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-manager:latest${SRC_POSTFIX}  ${docker_registry_org}/tubemq-manager:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-all:latest${SRC_POSTFIX}      ${docker_registry_org}/tubemq-all:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-build:latest${SRC_POSTFIX}    ${docker_registry_org}/tubemq-build:latest${DES_POSTFIX}
+  docker tag inlong/dashboard:latest${SRC_POSTFIX}       ${docker_registry_org}/dashboard:latest${DES_POSTFIX}
+  docker tag inlong/tubemq-cpp:latest${SRC_POSTFIX}      ${docker_registry_org}/tubemq-cpp:latest${DES_POSTFIX}
+  docker tag inlong/audit:latest${SRC_POSTFIX}           ${docker_registry_org}/audit:latest${DES_POSTFIX}
+
+  docker tag inlong/manager:${MVN_VERSION}${SRC_POSTFIX}         ${docker_registry_org}/manager:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/agent:${MVN_VERSION}${SRC_POSTFIX}           ${docker_registry_org}/agent:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/dataproxy:${MVN_VERSION}${SRC_POSTFIX}       ${docker_registry_org}/dataproxy:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-manager:${MVN_VERSION}${SRC_POSTFIX}  ${docker_registry_org}/tubemq-manager:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-all:${MVN_VERSION}${SRC_POSTFIX}      ${docker_registry_org}/tubemq-all:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-build:${MVN_VERSION}${SRC_POSTFIX}    ${docker_registry_org}/tubemq-build:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/dashboard:${MVN_VERSION}${SRC_POSTFIX}       ${docker_registry_org}/dashboard:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/tubemq-cpp:${MVN_VERSION}${SRC_POSTFIX}      ${docker_registry_org}/tubemq-cpp:${MVN_VERSION}${DES_POSTFIX}
+  docker tag inlong/audit:${MVN_VERSION}${SRC_POSTFIX}           ${docker_registry_org}/audit:${MVN_VERSION}${DES_POSTFIX}
+  echo "End tagging images"
+}
+
+publishImages() {
+  if [ -z "$DOCKER_USER" ]; then
+      echo "Docker user in variable \$DOCKER_USER was not set. Skipping image publishing"
+      exit 1
+  fi
+
+  if [ -z "$DOCKER_PASSWORD" ]; then
+      echo "Docker password in variable \$DOCKER_PASSWORD was not set. Skipping image publishing"
+      exit 1
+  fi
+
+  DOCKER_ORG="${DOCKER_ORG:-inlong}"
+
+  echo $DOCKER_PASSWORD | docker login ${DOCKER_REGISTRY} -u="$DOCKER_USER" --password-stdin
+  if [ $? -ne 0 ]; then
+      echo "Failed to login to ${DOCKER_REGISTRY}"
+      exit 1
+  fi
+
+  if [[ -z ${DOCKER_REGISTRY} ]]; then
+      docker_registry_org=${DOCKER_ORG}
+  else
+      docker_registry_org=${DOCKER_REGISTRY}/${DOCKER_ORG}
+      echo "Starting to push images to ${docker_registry_org}..."
+  fi
+
+  set -x
+
+  set -e
+
+  pushImage ${docker_registry_org}
+}
+
+pushDefaultImage() {
+  docker push inlong/manager:latest
+  docker push inlong/agent:latest
+  docker push inlong/dataproxy:latest
+  docker push inlong/tubemq-manager:latest
+  docker push inlong/tubemq-all:latest
+  docker push inlong/tubemq-build:latest
+  docker push inlong/dashboard:latest
+  docker push inlong/tubemq-cpp:latest
+  docker push inlong/audit:latest
+
+  docker push inlong/manager:${MVN_VERSION}
+  docker push inlong/agent:${MVN_VERSION}
+  docker push inlong/dataproxy:${MVN_VERSION}
+  docker push inlong/tubemq-manager:${MVN_VERSION}
+  docker push inlong/tubemq-all:${MVN_VERSION}
+  docker push inlong/tubemq-build:${MVN_VERSION}
+  docker push inlong/dashboard:${MVN_VERSION}
+  docker push inlong/tubemq-cpp:${MVN_VERSION}
+  docker push inlong/audit:${MVN_VERSION}
+}
+
+pushImage() {
+  echo "Start pushing images"
+  docker_registry_org=$1
+
+  SRC_POSTFIX=""
+  if [ "$BUILD_ARCH" = "$ARCH_AARCH64" ]; then
+    SRC_POSTFIX="-aarch64"
+  elif [ "$NEED_TAG" = true ]; then
+    pushDefaultImage
+    SRC_POSTFIX="-x86"
+  fi
+
+  docker push inlong/manager:latest${SRC_POSTFIX}
+  docker push inlong/agent:latest${SRC_POSTFIX}
+  docker push inlong/dataproxy:latest${SRC_POSTFIX}
+  docker push inlong/tubemq-manager:latest${SRC_POSTFIX}
+  docker push inlong/tubemq-all:latest${SRC_POSTFIX}
+  docker push inlong/tubemq-build:latest${SRC_POSTFIX}
+  docker push inlong/dashboard:latest${SRC_POSTFIX}
+  docker push inlong/tubemq-cpp:latest${SRC_POSTFIX}
+  docker push inlong/audit:latest${SRC_POSTFIX}
+
+  docker push inlong/manager:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/agent:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/dataproxy:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/tubemq-manager:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/tubemq-all:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/tubemq-build:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/dashboard:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/tubemq-cpp:${MVN_VERSION}${SRC_POSTFIX}
+  docker push inlong/audit:${MVN_VERSION}${SRC_POSTFIX}
+
+  echo "Finished pushing images to ${docker_registry_org}"
+}
+
+pushManifest() {
+  echo "Start pushing manifest ..."
+  docker manifest create --insecure --amend inlong/manager:latest        inlong/manager:latest-aarch64    inlong/manager:latest-x86
+  docker manifest create --insecure --amend inlong/agent:latest          inlong/agent:latest-aarch64      inlong/agent:latest-x86
+  docker manifest create --insecure --amend inlong/dataproxy:latest      inlong/dataproxy:latest-aarch64  inlong/dataproxy:latest-x86
+  docker manifest create --insecure --amend inlong/dashboard:latest      inlong/dashboard:latest-aarch64  inlong/dashboard:latest-x86
+  docker manifest create --insecure --amend inlong/audit:latest          inlong/audit:latest-aarch64      inlong/audit:latest-x86
+  docker manifest create --insecure --amend inlong/tubemq-cpp:latest     inlong/tubemq-cpp:latest-x86
+  docker manifest create --insecure --amend inlong/tubemq-manager:latest inlong/tubemq-manager:latest-x86
+  docker manifest create --insecure --amend inlong/tubemq-all:latest     inlong/tubemq-all:latest-x86
+  docker manifest create --insecure --amend inlong/tubemq-build:latest   inlong/tubemq-build:latest-x86
+
+  docker manifest push inlong/manager:latest
+  docker manifest push inlong/agent:latest
+  docker manifest push inlong/dataproxy:latest
+  docker manifest push inlong/tubemq-manager:latest
+  docker manifest push inlong/tubemq-all:latest
+  docker manifest push inlong/tubemq-build:latest
+  docker manifest push inlong/dashboard:latest
+  docker manifest push inlong/tubemq-cpp:latest
+  docker manifest push inlong/audit:latest
+
+  docker manifest create --insecure --amend inlong/manager:${MVN_VERSION}        inlong/manager:${MVN_VERSION}-aarch64    inlong/manager:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/agent:${MVN_VERSION}          inlong/agent:${MVN_VERSION}-aarch64      inlong/agent:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/dataproxy:${MVN_VERSION}      inlong/dataproxy:${MVN_VERSION}-aarch64  inlong/dataproxy:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/dashboard:${MVN_VERSION}      inlong/dashboard:${MVN_VERSION}-aarch64  inlong/dashboard:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/audit:${MVN_VERSION}          inlong/audit:${MVN_VERSION}-aarch64      inlong/audit:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/tubemq-manager:${MVN_VERSION} inlong/tubemq-manager:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/tubemq-all:${MVN_VERSION}     inlong/tubemq-all:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/tubemq-build:${MVN_VERSION}   inlong/tubemq-build:${MVN_VERSION}-x86
+  docker manifest create --insecure --amend inlong/tubemq-cpp:${MVN_VERSION}     inlong/tubemq-cpp:${MVN_VERSION}-x86
+
+  docker manifest push inlong/manager:${MVN_VERSION}
+  docker manifest push inlong/agent:${MVN_VERSION}
+  docker manifest push inlong/dataproxy:${MVN_VERSION}
+  docker manifest push inlong/tubemq-manager:${MVN_VERSION}
+  docker manifest push inlong/tubemq-all:${MVN_VERSION}
+  docker manifest push inlong/tubemq-build:${MVN_VERSION}
+  docker manifest push inlong/dashboard:${MVN_VERSION}
+  docker manifest push inlong/tubemq-cpp:${MVN_VERSION}
+  docker manifest push inlong/audit:${MVN_VERSION}
+
+  echo "End pushing manifest"
+}
+
+helpFunc() {
+  cat <<EOF
+Usage: ./publish-by-arch.sh [option]
+Options:
+  -b, --build           Add build operation before publish. Build docker images by arch.
+  -t, --tag             Add tag operation before publish. Add arch after version and add docker registry org.
+  -p, --publish         Publish images according to docker registry information.
+  -m, --manifest        Push manifest. This option doesn't need arch.
+  -x, --buildx <ARCH>   Use buildx to build docker images for another arch. This option doesn't need -b.
+                        Arch must be provided, as aarch64 or x86.
+  -h, --help            Show help information.
+Example:
+  Use "./publish-by-arch.sh -b" to publish arm images after build operation.
+  Use "./publish-by-arch.sh -t" to publish amd images after tag already x86 images as x86.
+  Use "./publish-by-arch.sh -x -p" to build arm docker images on x86 environment, then publish.
+EOF
+}
+
+for (( i=1; i<="$#"; i++)); do
+  if [ "${!i}" = "-b" ] || [ "${!i}" = "--build" ]; then
+    NEED_BUILD=true
+  elif [ "${!i}" = "-t" ] || [ "${!i}" = "--tag" ]; then
+    NEED_TAG=true
+  elif [ "${!i}" = "-m" ] || [ "${!i}" = "--manifest" ]; then
+    NEED_MANIFEST=true
+  elif [ "${!i}" = "-p" ] || [ "${!i}" = "--publish" ]; then
+    NEED_PUBLISH=true
+  elif [ "${!i}" = "-x" ] || [ "${!i}" = "--buildx" ]; then
+    NEED_BUILD=true
+    USE_BUILDX="--buildx"
+    j=$((i+1))
+    BUILD_ARCH=${!j}
+    if [ "$BUILD_ARCH" != "$ARCH_AARCH64" ] && [ "$BUILD_ARCH" != "$ARCH_X86" ]; then
+      echo "Wrong arch name: ${BUILD_ARCH}. Please input aarch64 or x86."
+      exit 1
+    fi
+    shift
+  elif [ "${!i}" = "-h" ] || [ "${!i}" = "--help" ]; then
+    helpFunc
+    exit 0
+  else
+    echo "Wrong param: ${!i}. Please check help information."
+    helpFunc
+    exit 1
+  fi
+done
+
+if [ "$NEED_BUILD" = true ]; then
+  buildImage
+fi
+
+if [ "$NEED_TAG" = true ]; then
+  tagImage
+fi
+
+if [ "$NEED_PUBLISH" = true ]; then
+  publishImages
+fi
+
+if [ "$NEED_MANIFEST" = true ]; then
+  pushManifest
+fi
diff --git a/docker/publish.sh b/docker/publish.sh
deleted file mode 100644
index 5ffb6364f..000000000
--- a/docker/publish.sh
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-if [ -z "$DOCKER_USER" ]; then
-    echo "Docker user in variable \$DOCKER_USER was not set. Skipping image publishing"
-    exit 1
-fi
-
-if [ -z "$DOCKER_PASSWORD" ]; then
-    echo "Docker password in variable \$DOCKER_PASSWORD was not set. Skipping image publishing"
-    exit 1
-fi
-
-DOCKER_ORG="${DOCKER_ORG:-inlong}"
-
-echo $DOCKER_PASSWORD | docker login ${DOCKER_REGISTRY} -u="$DOCKER_USER" --password-stdin
-if [ $? -ne 0 ]; then
-    echo "Failed to login to ${DOCKER_REGISTRY}"
-    exit 1
-fi
-
-MVN_VERSION=`python ./get-project-version.py`
-echo "InLong version: ${MVN_VERSION}"
-
-if [[ -z ${DOCKER_REGISTRY} ]]; then
-    docker_registry_org=${DOCKER_ORG}
-else
-    docker_registry_org=${DOCKER_REGISTRY}/${DOCKER_ORG}
-    echo "Starting to push images to ${docker_registry_org}..."
-fi
-
-set -x
-
-# Fail if any of the subsequent commands fail
-set -e
-
-# tag all images
-docker tag inlong/manager:latest     ${docker_registry_org}/manager:latest
-docker tag inlong/agent:latest           ${docker_registry_org}/agent:latest
-docker tag inlong/dataproxy:latest       ${docker_registry_org}/dataproxy:latest
-docker tag inlong/tubemq-manager:latest  ${docker_registry_org}/tubemq-manager:latest
-docker tag inlong/tubemq-all:latest      ${docker_registry_org}/tubemq-all:latest
-docker tag inlong/tubemq-build:latest    ${docker_registry_org}/tubemq-build:latest
-docker tag inlong/dashboard:latest         ${docker_registry_org}/dashboard:latest
-docker tag inlong/tubemq-cpp:latest      ${docker_registry_org}/tubemq-cpp:latest
-docker tag inlong/audit:latest      ${docker_registry_org}/audit:latest
-
-docker tag inlong/manager:$MVN_VERSION     ${docker_registry_org}/manager:$MVN_VERSION
-docker tag inlong/agent:$MVN_VERSION           ${docker_registry_org}/agent:$MVN_VERSION
-docker tag inlong/dataproxy:$MVN_VERSION       ${docker_registry_org}/dataproxy:$MVN_VERSION
-docker tag inlong/tubemq-manager:$MVN_VERSION  ${docker_registry_org}/tubemq-manager:$MVN_VERSION
-docker tag inlong/tubemq-all:$MVN_VERSION      ${docker_registry_org}/tubemq-all:$MVN_VERSION
-docker tag inlong/tubemq-build:$MVN_VERSION    ${docker_registry_org}/tubemq-build:$MVN_VERSION
-docker tag inlong/dashboard:$MVN_VERSION         ${docker_registry_org}/dashboard:$MVN_VERSION
-docker tag inlong/tubemq-cpp:$MVN_VERSION      ${docker_registry_org}/tubemq-cpp:$MVN_VERSION
-docker tag inlong/audit:$MVN_VERSION      ${docker_registry_org}/audit:$MVN_VERSION
-
-# Push all images and tags
-docker push inlong/manager:latest
-docker push inlong/agent:latest
-docker push inlong/dataproxy:latest
-docker push inlong/tubemq-manager:latest
-docker push inlong/tubemq-all:latest
-docker push inlong/tubemq-build:latest
-docker push inlong/dashboard:latest
-docker push inlong/tubemq-cpp:latest
-docker push inlong/audit:latest
-
-docker push inlong/manager:$MVN_VERSION
-docker push inlong/agent:$MVN_VERSION
-docker push inlong/dataproxy:$MVN_VERSION
-docker push inlong/tubemq-manager:$MVN_VERSION
-docker push inlong/tubemq-all:$MVN_VERSION
-docker push inlong/tubemq-build:$MVN_VERSION
-docker push inlong/dashboard:$MVN_VERSION
-docker push inlong/tubemq-cpp:$MVN_VERSION
-docker push inlong/audit:$MVN_VERSION
-
-echo "Finished pushing images to ${docker_registry_org}"