Sometimes, well, probably very rarely, you may have the use case where you have a Docker image that you want to share with a colleague or friend, but you don’t have a registry to upload it to. Luckily, there is another way you can do that with podman
by using the podman save
and podman load
commands. It’s super simple, here is how it’s done.
Saving the image to a tarball
The first step is to save the image to a tar ball. That’s where podman save
comes in, which is not to be confused with podman export
. The difference between the two is that podman save
saves a image to a file (aka a compressed tarball), while podman export
exports a container to a file.
podman save
comes only with a couple of options:
$ podman save --help
Save image(s) to an archive
Description:
Save an image to docker-archive or oci-archive on the local machine. Default is docker-archive.
Usage:
podman save [options] IMAGE [IMAGE...]
Examples:
podman save --quiet -o myimage.tar imageID
podman save --format docker-dir -o ubuntu-dir ubuntu
podman save > alpine-all.tar alpine:latest
Options:
--compress Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)
--format string Save image to oci-archive, oci-dir (directory with oci manifest type), docker-archive, docker-dir (directory with v2s2 manifest type) (default "docker-archive")
-m, --multi-image-archive Interpret additional arguments as images not tags and create a multi-image-archive (only for docker-archive)
-o, --output string Write to a specified file (default: stdout, which must be redirected)
-q, --quiet Suppress the output
--uncompressed Accept uncompressed layers when copying OCI images
In its simplest form, you can just invoke podman save -o my-file.tar <image name>
. Note that by default podman save
writes to stdout
so you can also redirect the save from there to a file (or anywhere else) via podman save > my-file.tar <image name>
.
Here is an example using the -o
option:
$ podman save -o gvenzl-oracle-free-23.5-slim.tar localhost/gvenzl/oracle-free:23.5-slim
Copying blob 53a5bb4f0279 done |
Copying blob 94e555c6b8cd done |
Copying blob ef6bbbd9d7cb done |
Copying blob efd5b62e86c9 done |
Copying blob e5eb5e3fb515 done |
Copying blob d6905b105e5d done |
Copying config 56f860e2a4 done |
Writing manifest to image destination
$ ls -alh gvenzl-oracle-free-23.5-slim.tar
-rw-r--r--. 1 gvenzl gvenzl 1.5G Aug 14 16:06 gvenzl-oracle-free-23.5-slim.tar
Loading the tarball as an image
Once your colleague or friend has the file, it can be loaded using podman load
, not to be confused with podman import
. Here again, podman load
loads the image from the tarball while podman import
creates a new image from a tarball but none of the run instructions such as ENTRYPOINT
, CMD
, or USER
. In other words, podman import
will just give you the contents of the tarball file as a new image but that image cannot spin up any containers for you.
Just like podman save
, podman load
is also fairly straight forward to use. It has the following options:
% podman load --help
Load image(s) from a tar archive
Description:
Loads an image from a locally stored archive (tar file) into container storage.
Usage:
podman load [options]
Options:
-i, --input string Read from specified archive file (default: stdin)
-q, --quiet Suppress the output
To load the image as is, just run podman load -i <tarball file>
:
% podman load -i gvenzl-oracle-free-23.5-slim.tar
Loaded image: localhost/gvenzl/oracle-free:23.5-slim
% podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/gvenzl/oracle-free 23.5-slim 56f860e2a4f1 10 hours ago 1.54 GB
Running the loaded image
Congrats, you now have the image loaded on another machine:
% podman run --name test -p 1521:1521 -e ORACLE_PASSWORD=LetsTest1 -e APP_USER=gerald -e APP_USER_PASSWORD=LetsTest1 gvenzl/oracle-free:23.5-slim
CONTAINER: starting up...
CONTAINER: first database startup, initializing...
CONTAINER: uncompressing database data files, please wait...
CONTAINER: done uncompressing database data files, duration: 3 seconds.
CONTAINER: starting up Oracle Database...
LSNRCTL for Linux: Version 23.0.0.0.0 - Production on 14-AUG-2024 16:39:07
Copyright (c) 1991, 2024, Oracle. All rights reserved.
Starting /opt/oracle/product/23ai/dbhomeFree/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 23.0.0.0.0 - Production
System parameter file is /opt/oracle/product/23ai/dbhomeFree/network/admin/listener.ora
Log messages written to /opt/oracle/diag/tnslsnr/fb5db676fb14/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC_FOR_FREE)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_FREE)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 23.0.0.0.0 - Production
Start Date 14-AUG-2024 16:39:07
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Default Service FREE
Listener Parameter File /opt/oracle/product/23ai/dbhomeFree/network/admin/listener.ora
Listener Log File /opt/oracle/diag/tnslsnr/fb5db676fb14/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC_FOR_FREE)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
The listener supports no services
The command completed successfully
ORACLE instance started.
Total System Global Area 1603726640 bytes
Fixed Size 5360944 bytes
Variable Size 771751936 bytes
Database Buffers 822083584 bytes
Redo Buffers 4530176 bytes
Database mounted.
Database opened.
CONTAINER: Resetting SYS and SYSTEM passwords.
User altered.
User altered.
CONTAINER: Creating app user for default pluggable database.
Session altered.
User created.
Grant succeeded.
CONTAINER: DONE: Creating app user for default pluggable database.
#########################
DATABASE IS READY TO USE!
#########################