How Podman can transfer container images without a registry
The new 'podman image scp' command makes it easier to transfer container images between users on the same system or machines over the network.
Have you ever built an image only to realize that you actually need it on a user account other than root, requiring you to rebuild the image again in rootless mode?
Or have you built an image on one machine but run containers on the image using multiple different machines? Now you need to set up an account on a registry, push the image to the registry, Secure Shell (SSH) to each device you want to run the image on, and then pull the image.
podman image scp command solves both of these annoying scenarios as quickly as they occur.
You can copy a root image to a non-root account like this:
$ podman image scp root@localhost::IMAGE USER@localhost::
Or copy an image from one machine to another with this command:
$ podman image scp firstname.lastname@example.org::IMAGE email@example.com::
Transferring images between local machines has traditionally involved an image registry like Quay.io, connecting to the internet, and pushing and pulling the image.
[ You might also be interested in learning 5 handy flags that make the Podman user experience better. ]
podman image scp, you can transfer images between local and remote machines without requiring an image registry.
Podman takes advantage of its SSH support to copy images between machines, and it also allows for local transfer. Registryless image transfer is useful in a couple of key scenarios:
- Doing a local transfer between users on one system
- Sharing images over the network
The next sections cover these examples in more detail.
1. Do local transfer between users on a system
You can use the
podman image scp command to transfer images between local users by using this command:
$ podman image scp USERNAME@localhost::$IMAGE root@localhost::
Specifying the destination is actually optional. If root is specified in the source, the default
$USER is assumed as the destination. If a user is specified and validated, root is assumed as the destination. For example, this transfers
$IMAGE to root:
$ podman image scp USERNAME@localhost::$IMAGE
This feature allows users to build images using either rootful or rootless permissions and transfer them seamlessly wherever they are needed. The command does not require
sudo to execute but prompts for validation midcommand if your user is not included in
You can also copy an image from root to a user account:
# podman image scp $IMAGE USERNAME@localhost::
sudo with a specific source and destination:
$ sudo podman image scp root@localhost::$IMAGE USERNAME@localhost::
Here's an example:
$ cat Containerfile FROM registry.fedoraproject.org/fedora:35 RUN dnf install -y podman CMD ["podman", "run", "-dt", "alpine"]
This simple Containerfile still takes some time to process if you run it for multiple user accounts. The
dnf command alone takes a long time to process.
$ podman build –file=Containerfile ... ... Complete! --> 18a64048b45 STEP 3/3: CMD ["podman", "run", "-dt", "alpine"] COMMIT --> fbf02ebb4eb Fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9
Oops, you realize you just built this on the wrong user. You meant to build it again as root:
$ sudo podman build –file=Containerfile
Or you could push the image, become root, and pull it from the registry, like this:
$ podman push \ fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9 \ dir:/tmp/scpimg Getting image source signatures Copying blob a4220bc9b4f9 done Copying blob ea810b5c3ace done Copying config fbf02ebb4e done Writing manifest to image destination Storing signatures $ sudo podman pull dir:/tmp/scpimg Getting image source signatures Copying blob a4220bc9b4f9 done Copying blob ea810b5c3ace done Copying config fbf02ebb4e done Writing manifest to image destination Storing signatures Fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9
Both of these options are time-consuming and potentially require a third-party registry.
podman image scp command simply copies the image between users:
$ podman image scp \ fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9 \ root@localhost:: Copying blob a4220bc9b4f9 done Copying blob ea810b5c3ace done Copying config fbf02ebb4e done Writing manifest to image destination Storing signatures Getting image source signatures Copying blob ea810b5c3ace skipped: already exists Copying blob a4220bc9b4f9 skipped: already exists Copying config fbf02ebb4e done Writing manifest to image destination Storing signatures Loaded image(s): sha256:fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9
This one command eliminates the need for a registry to temporarily store the image.
[ Keep key commands at your fingertips. Download the Intermediate Linux cheat sheet. ]
2. Share images between machines over the network
You can also use the
podman image scp command remotely. For example, to copy an image from a remote machine to your local system, type:
podman image scp USER@CONNECTION::$IMAGE
Or, to copy an image from your local machine to a remote machine, run:
$ podman image scp $IMAGE USERNAME@CONNECTION::
This example copies the image from a remote machine to a different remote machine:
podman image scp USER1@CONNECTION1::$IMAGE USER2@CONNECTION2::
Building an image on a machine and then distributing it to many systems can be even more laborious. You need to push the image to a registry, then SSH into each box you want the image on, and finally pull it back to that system. Given that you probably already have SSH configured to connect to the remote machines, just use
podman image scp to copy the image to each machine instead. All that's required is to configure the SSH connections using the
podman system connection add command. Execute the following:
$ podman system connection list Name URI Identity Default ubuntu ssh://firstname.lastname@example.org.[...]podman.sock /home/tux/.ssh/id_ubuntu true $ podman image scp \ fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9 \ ubuntu:: Copying blob 72e830a4dff5 done Copying config 85f9dc67c7 done Writing manifest to image destination Storing signatures Loaded image(s): sha256:fbf02ebb4eb454abf76715e6a7b0200c9e9a0add086cfb7a60eeed47a9b4e1c9
This single command has the same effect as pushing to and pulling from a remote registry without any of the related complications.
First, create a new SSH key using
ssh-keygen, send that key over to the remote SSH directory using
ssh-copy-id, and place that new key in the
authorized_keys file on the remote machine. Next, create a new connection using the following command:
$ ssh-copy-id -i <.pub file> -o IdentitiesOnly=yes REMOTE_USER_NAME@192.168.122.1
Next, create the connection using the
podman system connection add command:
$ podman system connection add CONNECTION -i ~/.ssh/id_ed25519 \ REMOTE_USER_NAME@192.168.122.1:22/run/user/1000/podman/podman.sock
Podman names the new connection
CONNECTION and uses the recently created SSH key. You need to specify the Podman socket on the remote machine so that the program knows where to execute commands.
Adding this connection allows you to refer to this address as
CONNECTION. Say you have an image named
my_image you want to send to this remote machine. Executing
podman image scp my_image CONNECTION:: results in:
$ podman image scp my_image CONNECTION:: Copying blob 72e830a4dff5 done Copying config 85f9dc67c7 done Writing manifest to image destination Storing signatures Loaded image(s): my_image:latest
my_image to the remote
CONNECTION. You can also retrieve an image from your newly established remote machine by executing:
$ podman image scp CONNECTION::my_image Copying blob 72e830a4dff5 done Copying config 85f9dc67c7 done Writing manifest to image destination Storing signatures Loaded image(s): my_image:latest
Finally, the image does not even have to be located locally. Put two connections into the command, one as a source and the other as a destination. In this example, you previously set up two additional connections, one named
ONE and the second called
$ podman image scp ONE::my_image TWO:: Copying blob 72e830a4dff5 done Copying config 85f9dc67c7 done Writing manifest to image destination Storing signatures Loaded image(s): my_image:latest
How it works
$ podman image scp root@localost::$IMAGE $USER@localhost::
The first new process is forked off the main
podman process, executing a
sudo podman image save. Then a second process is started by running the
podman image load command. The alternative command is:
$ podman image scp $USER@localost::$IMAGE root@localhost::
This transfers from user storage to root storage. Transferring between rootful and rootless storage is possible because
image scp does not enter the Podman namespace until it executes the proper load and saves commands. Not entering the Podman namespace allows
podman image scp to act as a wrapper function when performing local tasks.
podman image scp command circumvents retrieval of images from a traditional registry by utilizing sshd and executing new Podman processes. The ability to transfer images between users or networks allows more flexibility in sharing images with different machines. This feature's use in edge and secure environments are interesting to consider, as are the everyday uses.
Improve how you use containers with these new Podman features: --latest, --replace, --all, --ignore, and --tz.
Podman's new Netavark and Aardvark-based stack offers three main advantages over the existing CNI-based stack.
Keeping your images current is standard procedure for operating and managing a containerized environment. Here's how to do it.