One-click compilation of multi-platform Docker images with Github Action


The origin of containerization

In the early days of technology development, the Java language dominated many programming languages ​​with its “compile once, run anywhere” feature. The jar package compiled by Java language is always at the application level. If we want to run a jar package of a Web application, we still need to build a Tomcat server to actually run the Java application. So when the virtualization technology appeared, a complete virtualization image including Tomcat server and jar package and other necessary configuration and environment began to exist. As long as the corresponding virtualization software is installed on your computer or server, you can see the final Web interface and use it normally by running this virtualization image.

However, this also has an obvious disadvantage: the virtualization image file is usually large, the download speed is slow, and the time is long; the runtime virtualization software and virtual machine take up a lot of resources. Containerization technology is also born to solve these shortcomings. Docker is the earliest containerization technology open to the public, and has been well received by developers for its characteristics of “less resource occupation, small image files, and simple deployment and configuration”. After that, teams such as Google and Alibaba also opened up their own internal self-developed containerization-related technologies, such as Alibaba’s PouchContainer , Google’s Kubernetes , SUSE’s Rancher , and so on. These technologies and containerized platforms provided by cloud server manufacturers such as AWS, Azure, GCP, and Aliyun have greatly accelerated the popularization and application of containerized technologies. More and more platforms and applications have been migrated to containerized deployment and management.

Differences in Platform Architecture

In recent years, as large companies such as AWS and Apple have invested in the queue of self-developed chips, ARM chips with lower energy consumption and stronger computing power have begun to appear in real virtualized clusters, containerized clusters, and high-performance computing clusters. middle. Unlike the Intel or AMD x64 chips we use on our daily computers or servers, ARM chips are still relatively rare in reality, and the software package compatibility may not be very good. In addition, we usually compile Docker images on our own computer or server, so the final submitted image can only be the platform architecture of the computer or server. That said, we don’t seem to be able to compile the desired Docker image on an Intel-based device to support running on an ARM-based chip.

Here, we can take a look at all the platform architectures that Docker officially lists:

 // ... var SupportedArches = map [ string ] OCIPlatform { "amd64" : { OS : "linux" , Architecture : "amd64" }, "arm32v5" : { OS : "linux" , Architecture : "arm" , Variant : "v5" }, "arm32v6" : { OS : "linux" , Architecture : "arm" , Variant : "v6" }, "arm32v7" : { OS : "linux" , Architecture : "arm" , Variant : "v7" }, "arm64v8" : { OS : "linux" , Architecture : "arm64" , Variant : "v8" }, "i386" : { OS : "linux" , Architecture : "386" }, "mips64le" : { OS : "linux" , Architecture : "mips64le" }, "ppc64le" : { OS : "linux" , Architecture : "ppc64le" }, "riscv64" : { OS : "linux" , Architecture : "riscv64" }, "s390x" : { OS : "linux" , Architecture : "s390x" }, "windows-amd64" : { OS : "windows" , Architecture : "amd64" }, } ...

In fact, in addition to the ARM chip architecture, there are some unique architectures, such as IBM’s s390x architecture, RISC-V’s riscv64 architecture, and so on. General Docker images may only consider the common amd64 and 386 architectures, and there may be no so-called official support for other architectures. The author also found that the official support for almost all the platform architectures listed above when using Docker to deploy YOURLS is not too convenient. So I wondered how was this done? Did they use devices of different platforms to compile it again and then push it up? After some investigation, it was found that they may have used the Action provided by Github to automatically compile images for different platforms. But in fact all the configuration files under the .github/workflows directory have nothing to do with Docker image compilation. However, it is indeed feasible for Github Action to help us automatically compile Docker images for different platform architectures.

Automate builds

Here, the author only describes how to use Github Action to automatically compile Docker images for different platform architectures. If you want to know more about Github Action, you can check Ruan Yifeng’s “Introduction to Github Action” given in References.

Action configuration

Create a new docker-image.yml configuration file in the .github/workflows/ directory of the Github code base (the file name can be customized). The content of the file is as follows: (The slashes in front of the curly braces are used to avoid being parsed by Jekyll, please delete them when using)

 name : ci on : push : tags : - v* env : APP_NAME : squid DOCKERHUB_REPO : zhonger/squid jobs : docker : runs-on : ubuntu-latest steps : - name : Checkout uses : actions/[email protected] - name : Set up QEMU uses : docker/[email protected] - name : Set up Docker Buildx uses : docker/[email protected] - name : Login to DockerHub uses : docker/[email protected] with : username : ${\{ secrets.DOCKERHUB_USERNAME }} password : ${\{ secrets.DOCKERHUB_TOKEN }} - name : Generate App Version run : echo APP_VERSION=`git describe --tags --always` >> $GITHUB_ENV - name : Build and push uses : docker/[email protected] with : context : . platforms : | linux/386 linux/amd64 linux/arm/v5 linux/arm/v7 linux/arm64 linux/mips64le linux/ppc64le linux/s390x push : true build-args : | APP_NAME=${\{ env.APP_NAME }} APP_VERSION=${\{ env.APP_VERSION }} tags : | ${\{ env.DOCKERHUB_REPO }}:latest ${\{ env.DOCKERHUB_REPO }}:${\{ env.APP_VERSION }}

The contents of the file are explained as follows:

Process name

The name field defines the name of this process, which can be different from the configuration file name. As long as it is different from the process name in other process configuration files.

Triggering conditions

The on field defines under what conditions the process is triggered. The definition here is to trigger the process when a new tag starting with v is submitted.

environment variable

The env field defines static and public environment variables. Generally, the name of the application and the name of the image can be written in this section.


The jobs field defines the tasks that the process needs to perform, which can be one or more. There are 6 tasks defined here, from front to back: check whether the code is in the working directory, install qemu to support more architectures, install docker image compilation environment, log in to DockerHub, generate application version, build and push. The more flexible point here is that the tag of the Docker image is determined by the submitted tag name, so as to push the new tag and latest at the same time. In build and push tasks, the platforms field defines the platform architecture we want to support, the push field defines whether to push or not, build-args defines the variables added to the Docker image, and tags defines the tag value used after the build is complete.

Secret configuration

Since we need to protect the security of our DockerHub account and password, we need to pass the Secret variable to Github Action. As shown in the figure below, enter the Actions tab of the Secrets of Security in Settings, and add the corresponding DOCKERHUB_USERNAME and DOCKERHUB_TOKEN variables.

Post a new tag

Visit to reach the release page, as shown below. Define a new tag starting with v and point to the desired branch, fill in the title and description in turn, and click the Public release button to complete the release.

After the tag is released, Github Action will automatically start executing the above definition process, and finally successfully release Docker images that support different platform architectures to DockerHub. Of course, if you want to publish to other platforms, you can modify the image name and the corresponding verification method to be equally effective.


This article is reprinted from:
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment

Your email address will not be published.