Arch Linux Docker Image



  1. Arch Linux Arm Docker Image
  2. Arch Linux Docker Image
  3. Arch Linux Docker Image Centos
  4. Arch Linux Docker Container
  5. Arch Linux Docker Image Command
  6. Arch Linux Docker Images
  7. Arch Linux Docker Image Size

“Build once, deploy anywhere” is really nice on the paper but if you want to use ARM targets to reduce your bill, such as Raspberry Pis and AWS A1 instances, or even keep using your old i386 servers, deploying everywhere can become a tricky problem as you need to build your software for these platforms. To fix this problem, Docker introduced the principle of multi-arch builds and we’ll see how to use this and put it into production.

The Docker daemon pulled the 'hello-world' image from the Docker Hub. 2019 OS/Arch: linux/amd64. Mon May 6 18:46:08 UTC 2019 armv7l Linux $ docker run docker. Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 162 Server Version: 17.06.0-ce Storage Driver: aufs Root Dir: /var/lib/docker/aufs Backing Filesystem: extfs Dirs: 316 Dirperm1 Supported: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf. On Linux, you’ll have to edit /.docker/config.json and restart the engine. OK, now we understand why multi-arch images are interesting, but how do we produce them? How do they work? Each Docker image is represented by a manifest. A manifest is a JSON file containing all the information about a Docker image.

Quick setup

To be able to use the docker manifest command, you’ll have to enable the experimental features.

On macOS and Windows, it’s really simple. Open the Preferences > Command Line panel and just enable the experimental features.

On Linux, you’ll have to edit ~/.docker/config.json and restart the engine.

Under the hood

OK, now we understand why multi-arch images are interesting, but how do we produce them? How do they work?

Each Docker image is represented by a manifest. A manifest is a JSON file containing all the information about a Docker image. This includes references to each of its layers, their corresponding sizes, the hash of the image, its size and also the platform it’s supposed to work on. This manifest can then be referenced by a tag so that it’s easy to find.

For example, if you run the following command, you’ll get the manifest of a non-multi-arch image in the rustlang/rust repository with the nightly-slim tag:

$ docker manifest inspect --verbose rustlang/rust:nightly-slim
{
'Ref': 'docker.io/amd64/rust:1.42-slim-buster',
'Descriptor': {
'mediaType': 'application/vnd.docker.distribution.manifest.v2+json',
'digest': 'sha256:1bf29985958d1436197c3b507e697fbf1ae99489ea69e59972a30654cdce70cb',
'size': 742,
'platform': {
'architecture': 'amd64',
'os': 'linux'
}
},
'SchemaV2Manifest': {
'schemaVersion': 2,
'mediaType': 'application/vnd.docker.distribution.manifest.v2+json',
'config': {
'mediaType': 'application/vnd.docker.container.image.v1+json',
'size': 4830,
'digest': 'sha256:dbeae51214f7ff96fb23481776002739cf29b47bce62ca8ebc5191d9ddcd85ae'
},
'layers': [
{
'mediaType': 'application/vnd.docker.image.rootfs.diff.tar.gzip',
'size': 27091862,
'digest': 'sha256:c499e6d256d6d4a546f1c141e04b5b4951983ba7581e39deaf5cc595289ee70f'
},
{
'mediaType': 'application/vnd.docker.image.rootfs.diff.tar.gzip',
'size': 175987238,
'digest': 'sha256:e2f298701fbeb02568c3dcb9822f8488e24ef12f5430bc2e8562016ba8670f0d'
}
]
}

}

The question is now, how can we put multiple Docker images, each supporting a different architecture, behind the sametag?

Arch linux docker image size

What if this manifest file contained a list of manifests, so that the Docker Engine could pick the one that it matches at runtime? That’s exactly how the manifest is built for a multi-arch image. This type of manifest is called a manifest list.

Let’s take a look at a multi-arch image:

$ docker manifest inspect ‐‐verbose rust:1.42-slim-buster
[
{
'Ref': 'docker.io/library/rust:1.42-slim-buster@sha256:1bf29985958d1436197c3b507e697fbf1ae99489ea69e59972a30654cdce70cb',
'Descriptor': {
'mediaType': 'application/vnd.docker.distribution.manifest.v2+json',
'digest': 'sha256:1bf29985958d1436197c3b507e697fbf1ae99489ea69e59972a30654cdce70cb',
'size': 742,
'platform': {
'architecture': 'amd64',
'os': 'linux'
}
},
'SchemaV2Manifest': { ... }
},
{
'Ref': 'docker.io/library/rust:1.42-slim-buster@sha256:116d243c6346c44f3d458e650e8cc4e0b66ae0bcd37897e77f06054a5691c570',
'Descriptor': {
'mediaType': 'application/vnd.docker.distribution.manifest.v2+json',
'digest': 'sha256:116d243c6346c44f3d458e650e8cc4e0b66ae0bcd37897e77f06054a5691c570',
'size': 742,
'platform': {
'architecture': 'arm',
'os': 'linux',
'variant': 'v7'
}
},
'SchemaV2Manifest': { ... }
...
]

We can see that it’s a simple list of the manifests of all the different images, each with a platform section that can be used by the Docker Engine to match itself to.

How they’re made

There are two ways to use Docker to build a multiarch image: using docker manifest or using docker buildx.

To demonstrate this, we will need a project to play. We’ll use the following Dockerfile which just results in a Debian based image that includes the curl binary.

ARG ARCH=
FROM ${ARCH}debian:buster-slim
RUN apt-get update
&& apt-get install -y curl
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ 'curl' ]

Now we are ready to start building our multi-arch image.

The hard way with docker manifest

We’ll start by doing it the hard way with `docker manifest` because it’s the oldest tool made by Docker to build multiarch images.

To begin our journey, we’ll first need to build and push the images for each architecture to the Docker Hub. We will then combine all these images in a manifest list referenced by a tag.

# AMD64
$ docker build -t your-username/multiarch-example:manifest-amd64 --build-arg ARCH=amd64/ .
$ docker push your-username/multiarch-example:manifest-amd64
# ARM32V7
$ docker build -t your-username/multiarch-example:manifest-arm32v7 --build-arg ARCH=arm32v7/ .
$ docker push your-username/multiarch-example:manifest-arm32v7
# ARM64V8
$ docker build -t your-username/multiarch-example:manifest-arm64v8 --build-arg ARCH=arm64v8/ .
$ docker push your-username/multiarch-example:manifest-arm64v8

Now that we have built our images and pushed them, we are able to reference them all in a manifest list using the docker manifest command.

$ docker manifest create
your-username/multiarch-example:manifest-latest
--amend your-username/multiarch-example:manifest-amd64
--amend your-username/multiarch-example:manifest-arm32v7
--amend your-username/multiarch-example:manifest-arm64v8

Once the manifest list has been created, we can push it to Docker Hub.

$ docker manifest push your-username/multiarch-example:manifest-latest

If you now go to Docker Hub, you’ll be able to see the new tag referencing the images:

The simple way with docker buildx

You should be aware that buildx is still experimental.

If you are on Mac or Windows, you have nothing to worry about, buildx is shipped with Docker Desktop. If you are on linux, you might need to install it by following the documentation here https://github.com/docker/buildx

The magic of buildx is that the whole above process can be done with a single command.

Image

$ docker buildx build
--push
--platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag your-username/multiarch-example:buildx-latest .

And that’s it, one command, one tag and multiple images.

Let’s go to production

We’ll now try to target the CI and use GitHub Actions to build a multiarch image and push it to the Hub.

To do so, we’ll write a configuration file that we’ll put in .github/workflows/image.yml of our git repository.

Arch Linux Arm Docker Image

name: build our image
on:
push:
branches: master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v2
- name: install buildx
id: buildx
uses: crazy-max/ghaction-docker-buildx@v1
with:
version: latest
- name: build the image
run: |
docker buildx build
--tag your-username/multiarch-example:latest
--platform linux/amd64,linux/arm/v7,linux/arm64 .

Thanks to the GitHub Action crazy-max/docker-buildx we can install and configure buildx with only one step.

To be able to push, we now have to get an access token on Docker Hub in the security settings.

Once you created it, you’ll have to set it in your repository settings in the Secrets section. We’ll create DOCKER_USERNAME and DOCKER_PASSWORD variables to login afterward.

Now, we can update the GitHub Action configuration file and add the login step before the build. And then, we can add the --push to the buildx command.

...
- name: login to docker hub
run: echo '${{ secrets.DOCKER_PASSWORD }}' | docker login -u '${{ secrets.DOCKER_USERNAME }}' --password-stdin
- name: build the image
run: |
docker buildx build --push
--tag your-username/multiarch-example:latest
--platform linux/amd64,linux/arm/v7,linux/arm64 .

We now have our image being built and pushed each time something is pushed on master.

Conclusion

This post gives an example of how to build a multiarch Docker image and push it to the Docker Hub. It also showed how to automate this process for git repositories using GitHub Actions; but this can be done from any other CI system too.

An example of building multiarch image on Circle CI, Gitlab CI and Travis can be found here.

This blog post is the result of collaboration between Arm and Docker. Special thanks to Jason Andrews @ Arm for creating much of the original content.

Arm and Docker announced a strategic partnership earlier this year to unify software development and deployment across a diverse set of devices, from IoT endpoints to the edge of the network, and into the heart of the data center. Docker has simplified enterprise software development and deployment leading to true multi-platform portability and cost savings on Arm-based cloud instances. Even more exciting is how Docker is changing the way embedded software is being developed and deployed.

Traditionally embedded Linux software applications have been created by cross-compiling and copying files to an embedded target board. There are various methods to automate this process, but it has generally been unchanged since the 1990’s when non-x86 embedded possessors running Linux appeared. Docker stands to make the first significant change to the embedded Linux application developer’s workflow.

Arch Linux Docker Image

This article continues from Building Multi-Arch Images for Arm and x86 with Docker Desktop and shows the same capabilities in Linux. Although Windows and Mac support is great, the majority of software developers targeting embedded Linux systems also do their development work on Linux. The multi-architecture support in Docker also greatly simplifies embedded Linux application development and deployment.

If you are doing software development on x86 Linux machines and want to create Docker images that run on Arm servers or Arm embedded and IoT devices, this article will be helpful to understand the process and the different ways to do it.

Let’s see how to use Docker for Arm software development using the new buildx feature on Linux to create multi-architecture container images and run them. I’m using Ubuntu 18.04, but the same info applies to most any Linux distribution.

Install Docker

Installing Docker on Linux takes just a few commands. More installation info is available in the Docker Documentation.

If you already have an older version of Docker, make sure to uninstall it first. Using buildx requires Docker 19.03 and today the best way to get this is using the test instead of the stable version.

Add the current user to the docker group to avoid needing sudo to run the docker command:

Make sure to log out and back in again. Now test the install with a quick hello-world run.

Use the docker version command to check the running version:

Image

Install buildx for multi-architecture image builds

Size

There are three options to get buildx on Linux:

  • Use buildx directly from the test channel version of Docker
  • Download a binary release of buildx and copy it to the $HOME/.docker directory
  • Download, build, and install buildx from github.com
Use buildx from Docker test channel

The test version of Docker already has buildx included. The only thing needed is to set the environment variable to enable experimental command line features.

Download a binary release

Arch Linux Docker Image Centos

Another way to get buildx is to download a binary release from github and put in the .docker/cli-plugins directory.

For example, download the buildx for Linux amd64 with a browser from: https://github.com/docker/buildx/releases/tag/v0.2.0

Then copy it to the cli-plugins/ directory (create it first if necessary):

Download, build, and install buildx

Because buildx is a new command and documentation is still catching up, githubis a good place to read more information about how buildx works.

To get buildx from github use the commands:

To confirm buildx is now installed run the help and the version command.

Register Arm executables to run on x64 machines

Install the qemu instruction emulation to register Arm executables to run on the x86 machine. For best results, the latest qemu image should be used. If an older qemu is used some application may not work correctly on the x86 hardware.

To verify the qemu handlers are registered properly, run the following and make sure the first line of the output is “enabled”. Note that the handler registration doesn’t survive a reboot, but could be added to the system start-up scripts.

Arch Linux Docker Container

Arch Linux Docker Image

Create a multi-architecture build instance

Setup a new builder instance to create multi-architecture images.

Try buildx

There are multiple examples of buildx available, but here is a simple one for C programmers! Create a file named hello.c with this code:

Arch Linux Docker Image Command

Here is a Docker file to build and run it. Let’s get used to using multi-stage Docker files as it will be common for deploying embedded applications. Create a Dockerfile with the following:

Now, use buildx to build for multiple architectures and push to Docker hub.

Use docker login first if needed and substitute your own Hub account.

Run using the sha from the manifest and see the output from uname as armv7l, aarch64, and x86_64:

Next steps

Arch Linux Docker Images

As we have seen, building multi-architecture containers can be created with buildx in the same way as with Docker Desktop for Mac and Windows. Give it a try for yourself and start making the transition to multi-architecture Docker images today.

Arch Linux Docker Image Size

Further Reading