Skip to main content

How to push a multi-architecture Docker image to Docker Hub - 2

·607 words·3 mins
Multi-Architecture Docker image - This article is part of a series.
Part : This Article

How to push a multi-architecture Docker image to Docker Hub - Arm32v7 & Arm64v8
#

In the last post I took care of the x86_64 image generated by Docker Hub for us. The other images (Arm32v7 and Arm64v8) will have to be built at home with my own devices.

Get the manifest tool
#

I just downloaded a binary from the main Github repository. I chose version 0.7.0 for armv7 and arm64 architectures.

I just renamed to downloaded file and moved it to /usr/local/bin :

wget https://github.com/estesp/manifest-tool/releases/download/v0.7.0/manifest-tool-linux-arm64
mv manifest-tool-linux-arm64 manifest-tool
chmod +x manifest-tool
./manifest-tool --help # Just to check that it's working
mv manifest-tool /usr/local/bin/

It will be integrated into Docker but for now we don’t have any estimates on when.

Let’s do it
#

I built a small shell script to build and push all images (thanks to this French web site).

Let’s break it into smaller pieces to explain.

In case this script is modified in the future, everything below relates to updateHub.sh in revision 1cd5da3683ea14e63a37eab9cf9d653dd4159b5a.

Update local copy
#

if [ "$(git status --untracked-files=no --porcelain)" ]; then
  echo "Uncommitted changes. Exiting..."
  exit 1
fi

git pull --rebase

To avoid any errors the script fail if there is uncommitted / modified files. New files are allowed. If that’s OK let’s pull new commits.

Set some variables
#

TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
MAJMIN=`echo $TAG | cut -d . -f 1,2 `
ARCH=`dpkg --print-architecture`
  • TAG to the latest tag in the repository, let’s say 3.6.6.
  • MAJMIN will only keep the major and minor number so 3.6.
  • ARCH will be set to the dpkg (Debian) architecture so armhf / arm64.

Update working copy to latest tag
#

git checkout $TAG

Loop over all images
#

for dir in alpine-python3 alpine-python2 alpine-mosquitto alpine-minidlna alpine-nginx alpine-python3-cron alpine-nginx-php
do
 ...
done

Here I loop over all the image I want to push on Docker Hub. The order is important if there are some dependency (alpine-python3 has to be before alpine-python3-cron)

Check if the image already exists
#

NBARCH=`manifest-tool inspect seblucas/$dir:$TAG | grep "Arch:" | wc -l`
if [[ $NBARCH -gt 1 ]]; then
    echo "Image seblucas/$dir:$TAG already uptodate"
    continue
fi

I’m not proud of this, I have to check if the image already exists on Docker Hub, I have not found a clever way so I’m using manifest-tool to check the image manifest and count the number of arch which has to be greater than 1.

If you have a better idea, please post a comment or propose a PR ;).

Build and push the image
#

cd $dir
docker build . -t seblucas/$dir:$ARCH-$TAG -t seblucas/$dir:$MAJMIN
docker push seblucas/$dir:$ARCH-$TAG

Again to handle image dependency we generate an additional local tag.

Push the manifest
#

if [[ $ARCH == "armhf" ]]; then
  echo "Manifest uploading ..."
  sed -i "s|{image}|$dir|g" ../manifest.yaml
  sed -i "s|{tag}|$TAG|g" ../manifest.yaml
  sed -i "s|{majmin}|$MAJMIN|g" ../manifest.yaml
  manifest-tool push from-spec ../manifest.yaml
  git checkout $TAG -- ../manifest.yaml
fi

I’ve created a basic manifest with placeholders that I replace with sed. Then I just push the manifest and that’s done.

Conclusion
#

That’s it, that wasn’t that hard to do. If you spot any errors / enhancements, please share them with me.

The big downside I see is that I have to follow an order : amd64 then arm64v8 and finally arm32v7. So for 2 hours the multi-architecture image is not really ready.

Todo
#

Maybe for a next episode in the serie :

  • Actually test the script in cron (for now I start it manually).
  • Explain how to use mplatform/mquery.
  • Delete the unneeded tags in Docker Hub (amd64-{TAG}, armhf-{TAG}, …), maybe by using Docker Hub Api.
  • Add other architectures.
Multi-Architecture Docker image - This article is part of a series.
Part : This Article