skip to Main Content

I have a scenario where I need to bundle a multi-container system in an exportable, transportable format. Specifically, I need to get an image from Docker Hub and store it on portable media (e.g. USB drive) that I can then load into an air-gapped machine with no internet access.

I can normally do this with:

# On the development server
docker pull nginx:1.23
docker save -o nginx.tar nginx:1.23

... store the .tar on portable media...

# On the air-gapped machine
docker load < myimage.tar

However, although the image is built for and supports multiple architectures, this appears to only store the image for a single architecture (the architecture of the machine that ran the docker pull). I need it to export images for all architectures to .tar files, so they can be loaded on machines of any architecture.

I’ve tried:

docker pull --platform linux/amd64 nginx:1.23
docker pull --platform linux/arm64 nginx:1.23

To manually specify that both the amd64 and arm64 images should be pulled, but the docker save still exports only a single image (which we can tell from the fact that the manifest.json file only has a single entry).

I’ve also tried:

docker pull --platform linux/amd64 --platform linux/arm64 nginx:1.23

But it has the same result.

How can I export/save an image with support for multiple different architectures when I docker load it? Ideally, I’d be able to docker load a single .tar file on a machine of any supported architecture, have it import the image for that architecture, then run the image.

EDIT:

After some further testing, I’ve found that if I do the following:

docker pull --platform linux/amd64 nginx:1.23
docker save -o nginx.tar

Then the .tar file has a manifest.json with a single image (for amd64). However, if I do this:

docker pull --platform linux/arm64 nginx:1.23
docker save -o nginx.tar

Then the .tar file has a manifest.json with two images (for amd64 and arm64).

This isn’t an issue with "you have to pull both" though; if I pull the amd64 version again, and docker save again, we’re back to a single image in the manifest.json. The order of pulls does appear to matter.

2

Answers


  1. From my post on the vastly superior DevOps SE:

    This is answered in the Docker blog post on multi-platform docker builds. For your specific situation, you would perform a build and push for each platform you’d like, then create a manifest file and push that. Then you can perform the save. It would look something like this:

    $ docker buildx build --platform linux/amd64 --push -t localhost:5000/myimage:amd64 .
    $ docker buildx build --platform linux/arm64 --push -t localhost:5000/myimage:arm64 .
    $ docker manifest create myimage:latest myimage:amd64 myimage:arm64
    $ docker manifest push localhost:5000/myimage:latest
    $ docker image save -o myimage.tar localhost:5000/myimage:latest
    
    Login or Signup to reply.
  2. How can I export/save an image with support for multiple different architectures when I docker load it? Ideally, I’d be able to docker load a single .tar file on a machine of any supported architecture, have it import the image for that architecture, then run the image.

    At present, you can’t. The docker engine currently only supports images with a single platform, so when you pull an image, it gets dereferenced to your selected platform. This is changing soon with how docker uses the containerd backend, since containerd supports multi-platform images. Until then, the two places you can store a multi-platform image are using a registry and using an OCI Layout syntax for storing the image on disk (that format is a little different than the format docker save and load uses).

    For copying between registries and/or the OCI layout, you don’t need the docker engine. Various tools support this, including Google’s crane, RedHat’s skopeo, and my own regclient. E.g. for an isolated environment where you import tar files:

    regctl image export nginx:1.23 nginx.tar
    # copy tar image to host in isolated environment
    regctl image import internal-registry.example.org/library/nginx nginx.tar
    docker pull internal-registry.example.org/library/nginx
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search