Let’s imagine you have 2 docker servers, one is your DEV server with access to registries and the internet, and another one it’s you PRD server which you can access with ssh.

Let me ilustrate the scenario:

graph LR subgraph internet INTERNET["Internet / Registries"] end subgraph Environments subgraph public-net DEV["Docker DEV server"] end subgraph private-net PRD["Docker PRD server"] end public-net <---> private-net end INTERNET <--- DEV

If the PRD server can’t access any registry and the internet, it can’t docker pull any remote image. Can you imagine a way you can ship docker images to it?

Well with docker / podman we can save a set of images into a tarball file, and then use the file to load the images on the other server.

PS: This is a hypothetical scenario, we usually have to put PRD isolated and secure, but at the same time CI/CD should be able to push images as well.

Saving the images to the tarball

First the images have to be on your own docker / podman server, so pull the image(s):

podman pull docker.io/library/nginx:latest

We can include several images on the tarball.

podman save \
 docker.io/library/golang:alpine \
 docker.io/library/nginx:latest -o app-images.tar

And here’s the local file generated:

ls -lhtr app-images.tar
-rw-r--r--@ 1 fsouza  staff   422M Sep  7 11:37 app-images.tar
:warning: Warning
When saving the same image but several tags, don’t forget to use the -m option, or --multi-image-archive, otherwise podman save sees the other images in the argument as just tags to be saved as well.
Example:
podmman save -m localhost/myimage:v1.0.0 localhost/myimage:v2.0.0 -o myimages.tar
Loading on the other server

Now we can simply copy the image to the other server with scp or rsync.

scp app-images.tar user@prodserver:/path 

And then we can now just load the images podman on the server.

The load command expects the tarball file as stdin, or the -i argument.

podman load < app-images.tar
podman load -i app-images.tar

Updated: