Add Multi Platform Build for Docker-Hub
Credits to https://github.com/rmoriz/multiarch-test
This commit is contained in:
parent
acf2cd32b3
commit
6bfb42584b
9 changed files with 241 additions and 76 deletions
|
|
@ -5,8 +5,11 @@ COPY ui ./
|
||||||
RUN npm install && \
|
RUN npm install && \
|
||||||
node_modules/.bin/ng build --prod
|
node_modules/.bin/ng build --prod
|
||||||
|
|
||||||
|
ARG BASE_IMAGE_PREFIX
|
||||||
|
FROM ${BASE_IMAGE_PREFIX}python:3.8-alpine
|
||||||
|
|
||||||
FROM python:3.8-alpine
|
ARG ARCH
|
||||||
|
COPY qemu-${ARCH}-static* /usr/bin
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -70,22 +70,6 @@ A Docker image can be built locally (it will build the UI too):
|
||||||
docker build -t metube .
|
docker build -t metube .
|
||||||
```
|
```
|
||||||
|
|
||||||
A Multi-Platform Docker image can be built locally:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build with tag "metube"
|
|
||||||
build-multi-platform.sh
|
|
||||||
|
|
||||||
# Build with tag "other_tag"
|
|
||||||
build-multi-platform.sh -t "other_tag"
|
|
||||||
|
|
||||||
# Build with tag "metube" and Upload do Docker Registry
|
|
||||||
build-multi-platform.sh -p
|
|
||||||
|
|
||||||
# Build with tag "other_tag" and Upload do Docker Registry
|
|
||||||
build-multi-platform.sh -t "other_tag" -p
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development notes
|
## Development notes
|
||||||
|
|
||||||
* The above works on Windows as well as Linux.
|
* The above works on Windows as well as Linux.
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
TAG="metube"
|
|
||||||
PUSH="false"
|
|
||||||
|
|
||||||
# Proccess Arguments
|
|
||||||
|
|
||||||
while getopts ":hhelpf:t:p:" ARGS;
|
|
||||||
do
|
|
||||||
case $ARGS in
|
|
||||||
h|help )
|
|
||||||
echo -e "Usgae:\n\t-t \"Tag\"\n\t\tuse a specific Tag\n\t-p\n\t\tPush the Image do a registry. Needs to be logged in (docker login).\n\t-h\n\t\t Show this Help Dialog"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
t )
|
|
||||||
TAG="${OPTARG}"
|
|
||||||
;;
|
|
||||||
p )
|
|
||||||
PUSH="true"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Fail on Error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Register Arm executables to run on x64 machines
|
|
||||||
docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
|
|
||||||
|
|
||||||
# Test if qemu is enabeld
|
|
||||||
cat /proc/sys/fs/binfmt_misc/qemu-aarch64 | head -n 1 | grep -q "enabled"
|
|
||||||
|
|
||||||
# Create a Builder if needed
|
|
||||||
if docker buildx ls | grep -q "multiArchBuilder"; then
|
|
||||||
echo "Builder \"multiArchBuilder\" aready exists."
|
|
||||||
else
|
|
||||||
echo "Builder \"multiArchBuilder\" will be created."
|
|
||||||
|
|
||||||
docker buildx create --name "multiArchBuilder"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Switch to Builder "multiArchBuilder"
|
|
||||||
docker buildx use "multiArchBuilder"
|
|
||||||
|
|
||||||
# Test if current Builder Contains needed Architectures
|
|
||||||
BOOTSTRAP=$(docker buildx inspect --bootstrap)
|
|
||||||
|
|
||||||
echo $BOOTSTRAP | grep -q "linux/amd64"
|
|
||||||
echo $BOOTSTRAP | grep -q "linux/arm64"
|
|
||||||
echo $BOOTSTRAP | grep -q "linux/arm/v7"
|
|
||||||
|
|
||||||
# Build Image
|
|
||||||
echo "Use Tag \"$TAG\" for Build"
|
|
||||||
if [ "$PUSH" = "true" ]; then
|
|
||||||
# Build with Push
|
|
||||||
docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t "$TAG" --push .
|
|
||||||
else
|
|
||||||
# Build without Push
|
|
||||||
docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t "$TAG" .
|
|
||||||
fi
|
|
||||||
54
hooks/.config
Normal file
54
hooks/.config
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set +u
|
||||||
|
echo "variables (see https://docs.docker.com/docker-hub/builds/advanced/):"
|
||||||
|
echo "SOURCE_BRANCH: $SOURCE_BRANCH"
|
||||||
|
echo "SOURCE_COMMIT: $SOURCE_COMMIT"
|
||||||
|
echo "COMMIT_MSG: $COMMIT_MSG"
|
||||||
|
echo "DOCKER_REPO: $DOCKER_REPO"
|
||||||
|
echo "DOCKERFILE_PATH: $DOCKERFILE_PATH"
|
||||||
|
echo "CACHE_TAG: $CACHE_TAG"
|
||||||
|
echo "IMAGE_NAME: $IMAGE_NAME"
|
||||||
|
echo
|
||||||
|
|
||||||
|
: "${DOCKERFILE_PATH:=./Dockerfile}"
|
||||||
|
: "${IMAGE_NAME:=rmoriz/openra}"
|
||||||
|
|
||||||
|
echo "variables after applying defaults:"
|
||||||
|
echo "DOCKERFILE_PATH: $DOCKERFILE_PATH"
|
||||||
|
echo "IMAGE_NAME: $IMAGE_NAME"
|
||||||
|
echo
|
||||||
|
|
||||||
|
export PATH="$PWD/docker:$PATH"
|
||||||
|
|
||||||
|
# =>
|
||||||
|
# https://hub.docker.com/u/arm64v8/
|
||||||
|
# https://hub.docker.com/u/arm32v7/
|
||||||
|
# https://hub.docker.com/u/arm32v6/
|
||||||
|
# https://hub.docker.com/u/arm32v5/
|
||||||
|
declare -A base_image_prefix_map=( ["aarch64"]="arm64v8/" ["arm"]="arm32v5/" ["amd64"]="")
|
||||||
|
|
||||||
|
# => dpkg -L qemu-user-static | grep /usr/bin/
|
||||||
|
declare -A docker_qemu_arch_map=( ["aarch64"]="aarch64" ["arm"]="arm" ["amd64"]="x86_64")
|
||||||
|
|
||||||
|
# => https://github.com/docker/docker-ce/blob/76ac3a4952a9c03f04f26fc88d3160acd51d1702/components/cli/cli/command/manifest/util.go#L22
|
||||||
|
declare -A docker_to_manifest_map=( ["aarch64"]="arm64" ["arm"]="arm" ["amd64"]="amd64")
|
||||||
|
|
||||||
|
# what we want to build
|
||||||
|
build_architectures=(amd64)
|
||||||
|
verified_build_architectures=()
|
||||||
|
verified_build_architectures+=("$(docker version -f '{{.Server.Arch}}')")
|
||||||
|
|
||||||
|
# what we can build
|
||||||
|
for arch in ${build_architectures[@]}; do
|
||||||
|
if [ -f "qemu-${docker_qemu_arch_map[${arch}]}-static" ]; then
|
||||||
|
echo "qemu binary for $arch found";
|
||||||
|
verified_build_architectures+=($arch)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $verified_build_architectures
|
||||||
|
set -u
|
||||||
|
|
||||||
|
docker -v
|
||||||
|
echo
|
||||||
57
hooks/build
Normal file
57
hooks/build
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
echo "🔵 build"
|
||||||
|
source hooks/.config
|
||||||
|
|
||||||
|
echo "✅ Will build the following architectures: $verified_build_architectures"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
|
||||||
|
for arch in ${verified_build_architectures[@]}; do
|
||||||
|
echo "✅ building $arch"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
|
||||||
|
BASE_IMAGE_PREFIX="${base_image_prefix_map[${arch}]}"
|
||||||
|
docker build \
|
||||||
|
--build-arg BASE_IMAGE_PREFIX=${BASE_IMAGE_PREFIX} \
|
||||||
|
--build-arg ARCH=${arch} \
|
||||||
|
--file $DOCKERFILE_PATH \
|
||||||
|
--tag "${IMAGE_NAME}-${arch}" \
|
||||||
|
.
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ images built:"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
docker image ls
|
||||||
|
|
||||||
|
# https://github.com/moby/moby/issues/36552
|
||||||
|
#
|
||||||
|
tempdir=$(mktemp -d -t yolo.XXXXXXXX)
|
||||||
|
cd $tempdir
|
||||||
|
|
||||||
|
for arch in ${verified_build_architectures[@]}; do
|
||||||
|
echo "✅ yolo fixing platform $arch"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
|
||||||
|
manifest_arch=${docker_to_manifest_map[${arch}]}
|
||||||
|
docker save "${IMAGE_NAME}-${arch}"| tar xv
|
||||||
|
|
||||||
|
for filename in */json; do
|
||||||
|
[ -e "$filename" ] || continue
|
||||||
|
jq --compact-output 'del(.architecture)' < "$filename" | sponge "$filename"
|
||||||
|
done
|
||||||
|
|
||||||
|
for filename in *.json; do
|
||||||
|
[ -e "$filename" ] || continue
|
||||||
|
! [ $filename = "manifest.json" ] || continue
|
||||||
|
|
||||||
|
jq --arg architecture "$manifest_arch" \
|
||||||
|
--compact-output '.architecture=$architecture' < "$filename" | sponge "$filename"
|
||||||
|
done
|
||||||
|
|
||||||
|
tar cv . | docker load
|
||||||
|
rm -rf $tempdir/*
|
||||||
|
done
|
||||||
|
|
||||||
|
trap "exit 1" HUP INT PIPE QUIT TERM
|
||||||
|
trap "rm -rf $tempdir" EXIT
|
||||||
15
hooks/get-qemu.sh
Normal file
15
hooks/get-qemu.sh
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# NOTE: this url will change regularly because it's unstable
|
||||||
|
PACKAGE=http://ftp.de.debian.org/debian/pool/main/q/qemu/qemu-user-static_4.2-2_amd64.deb
|
||||||
|
|
||||||
|
mkdir tmp/
|
||||||
|
cd tmp/
|
||||||
|
|
||||||
|
curl $PACKAGE -o $(basename ${PACKAGE})
|
||||||
|
dpkg-deb -X $(basename ${PACKAGE}) .
|
||||||
|
cp usr/bin/qemu-aarch64-static ..
|
||||||
|
cp usr/bin/qemu-arm-static ..
|
||||||
|
cd ..
|
||||||
|
rm -rf tmp
|
||||||
48
hooks/post_checkout
Normal file
48
hooks/post_checkout
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
echo "🔵 post_checkout"
|
||||||
|
source hooks/.config
|
||||||
|
|
||||||
|
echo "✅ Install qemu + binfmt support"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
# it's an Ubuntu VM and you can install stuff.
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl qemu-user-static binfmt-support jq moreutils
|
||||||
|
|
||||||
|
# Sadly docker itself uses Docker EE 17.06 on Dockerhub which does not support
|
||||||
|
# manifests.
|
||||||
|
echo "✅ Install a fresh docker cli binary"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
|
||||||
|
curl https://download.docker.com/linux/static/stable/x86_64/docker-18.09.1.tgz | \
|
||||||
|
tar xvz docker/docker
|
||||||
|
|
||||||
|
echo "✅ Build a usable config.json file"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
# Manifests are still experimental and enabled by a config file flag.
|
||||||
|
# Interestingly, there is no config file and the credential parts to push
|
||||||
|
# images is available in an environment variable. Let's create a config file to
|
||||||
|
# combine the two things:
|
||||||
|
#
|
||||||
|
mkdir -p ~/.docker
|
||||||
|
jq --null-input --argjson auths "$DOCKERCFG" '. + {auths: $auths}' | \
|
||||||
|
jq --arg experimental enabled '. + {experimental: $experimental}' | \
|
||||||
|
sponge ~/.docker/config.json
|
||||||
|
|
||||||
|
echo "✅ Copy qemu binaries into docker build context"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
# The current setup copies the qemu binary into the image (see Dockerfile)
|
||||||
|
# Pro:
|
||||||
|
# - it's easy to run non-amd64 images on amd64 systems for debugging
|
||||||
|
# Contra:
|
||||||
|
# - it's dead weight in the "destination" architecture and consumes space
|
||||||
|
# Alternative:
|
||||||
|
# - use a multistage Dockerfile (no RUN in the last stage possible of course)
|
||||||
|
# - wait for https://github.com/moby/moby/issues/14080
|
||||||
|
#
|
||||||
|
for arch in ${build_architectures[@]}; do
|
||||||
|
cp /usr/bin/qemu-${docker_qemu_arch_map[${arch}]}-static qemu-${arch}-static
|
||||||
|
done
|
||||||
|
|
||||||
|
ls -la
|
||||||
10
hooks/pre_build
Normal file
10
hooks/pre_build
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
echo "🔵 pre_build"
|
||||||
|
source hooks/.config
|
||||||
|
|
||||||
|
echo "✅ Register qemu-*-static for all supported processors except current"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
|
||||||
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
53
hooks/push
Normal file
53
hooks/push
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
echo "🔵 push"
|
||||||
|
source hooks/.config
|
||||||
|
|
||||||
|
# 1. push all images
|
||||||
|
IMAGE_NAME="${IMAGE_NAME//index.docker.io\/}"
|
||||||
|
|
||||||
|
for arch in ${verified_build_architectures[@]}; do
|
||||||
|
echo "✅ Pushing ${IMAGE_NAME}-${arch}"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
echo
|
||||||
|
docker push ${IMAGE_NAME}-${arch}
|
||||||
|
done
|
||||||
|
|
||||||
|
docker image ls
|
||||||
|
|
||||||
|
# 2. build and push manifest
|
||||||
|
#DOCKER_REPO="index.docker.io/${DOCKER_REPO}"
|
||||||
|
manifests=""
|
||||||
|
|
||||||
|
for arch in ${verified_build_architectures[@]}; do
|
||||||
|
manifests="${manifests} ${IMAGE_NAME}-${arch}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Creating manifest ${IMAGE_NAME}"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
docker manifest create ${IMAGE_NAME} \
|
||||||
|
$manifests
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "✅ Annotating manifest"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
for arch in ${verified_build_architectures[@]}; do
|
||||||
|
docker manifest annotate ${IMAGE_NAME} \
|
||||||
|
${IMAGE_NAME}-${arch} \
|
||||||
|
--os linux \
|
||||||
|
--arch ${docker_to_manifest_map[${arch}]}
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Inspecting manifest ${IMAGE_NAME}-${arch}"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
docker manifest inspect ${IMAGE_NAME}-${arch}
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "✅ Pushing manifest ${IMAGE_NAME}"
|
||||||
|
echo "⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯"
|
||||||
|
docker manifest push --purge "${IMAGE_NAME}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "😊"
|
||||||
Loading…
Reference in a new issue