Differences between docker save and docker export

This article talks about the difference between docker save and docker export.

Both docker save and docker export can export image packages. What are the functions of docker save and docker export? What application scenarios are applicable?

The tested version of docker in this article is as follows. It is not guaranteed that all versions of docker can reproduce the results of this article.

# docker version
Client: Docker Engine - Community
 Version:           19.03.11
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        42e35e61f3
 Built:             Mon Jun  1 09:13:48 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.11
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       42e35e61f3
  Built:            Mon Jun  1 09:12:26 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

docker save

The command-line interface of docker is designed elegantly. Many command help can be viewed directly after -- help.

The help of docker save is as follows:

[root@docker ~]# docker save --help

Usage:  docker save [OPTIONS] IMAGE [IMAGE...]

Save one or more images to a tar archive (streamed to STDOUT by default)

Options:
  -o, --output string   Write to a file, instead of STDOUT

As can be seen from the command line help, docker save is a tool used to package and save one or more image s.

For example, if we want to package postgres and mongo in the image library, we can execute:

docker save -o images.tar postgres:9.6 mongo:3.4

Packed images.tar contain postgres:9.6 and mongo:3.4 These two images.

Although the command line parameter requires image to be specified, the container can also be packaged, for example:

>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
3623943d369f        postgres:9.6        "docker-entrypoint..."   3 hours ago         Up 3 hours          5432/tcp            postgres
>docker save -o b.tar postgres
>docker save -o c.tar postgres:9.6
>ls -al
-rwxrwxrwx 1 root root 277886464 8month 26 14:40 b.tar
-rwxrwxrwx 1 root root 277886464 8month 26 14:41 c.tar

As like as two peas, you can see that b.tar and c.tar are exactly the same. This means that if the container is specified by docker save, the image behind the container will be saved by docker save.

Load the packed image in and use docker load, for example:

docker load -i images.tar

The above order will postgres:9.6 and mongo:3.4 If these two images already exist in the local image library, they will be overwritten.

The application scenario of docker save is that if your application uses docker-compose.yml The client server you are deploying cannot be connected to the Internet. At this time, you can use docker save to print a package of the image used, and then copy it to the client server to load it using docker load.

docker export

Check the help of docker export as usual:

[root@docker ~]# docker export --help

Usage:  docker export [OPTIONS] CONTAINER

Export a container's filesystem as a tar archive

Options:
  -o, --output string   Write to a file, instead of STDOUT

As can be seen from the help, docker export is used to package the container's file system. For example:

docker export -o postgres-export.tar postgres

docker export needs to specify a container. You cannot specify either image or container like docker save.

Load the packed container in and use docker import, for example:

docker import postgres-export.tar postgres:latest

As can be seen from the above command, when docker import imports a container, it will become an image rather than a container.

Another point is that docker import can specify IMAGE[:TAG], which means that we can specify a new name for the image. If an image with the same name already exists in the local image library, the name of the original image will be deprived and assigned to the new image. The original image will become a ghost, and can only be operated through IMAGE ID.

The application scenario of docker export is mainly used to make a basic image. For example, you start a container from a ubuntu image, install some software and make some settings, and then use docker export to save it as a basic image. Then, distribute the image to others, such as the underlying development environment.

The difference between docker save and docker export

To summarize the differences between docker save and docker export:

  1. docker save saves image, and docker export saves container;
  2. docker load is used to load the image package, and docker import is used to load the container package, but both of them will be restored to image;
  3. docker load cannot rename the loaded image, while docker import can specify a new name for the image.

contrast

The contents mentioned above are all basic knowledge. I believe that readers can know it only by looking at the official documents carefully. In this section, I will talk about something that is not on the document.

Both docker load and docker import can import tar packages as images. I can't help but wonder if docker load can import container packages of docker export and docker import can import image packages of docker save?

Start the test as follows and prepare the following two documents:

>ls -al
-rwxrwxrwx 1 root root 271760384 8month  26 12:15 postgres-export.tar
-rwxrwxrwx 1 root root 398292480 8month  26 12:13 postgres-save.tar

Including postgres-export.tar Is a container package exported through docker export, postgres-save.tar The image package saved by docker save is based on postgres:9.6 Mirror image. From the file size, you can intuitively find that postgres-export.tar Obviously better than postgres-save.tar More than 100 M smaller.

Now try the docker load container package postgres-export.tar :

>docker load -i postgres-export.tar
open /var/lib/docker/tmp/docker-import-082344818/bin/json: no such file or directory

Obviously, docker load cannot load the container package.

In turn, can docker import load the image package?

>docker import postgres-save.tar postgres
sha256:8910feec1ee2fac8c152dbdd0aaab360ba0b833af5c3ad59fcd648b9a24d4838
>docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
postgres                                        latest              8910feec1ee2        2 minutes ago       398MB

Try starting a postgres container again:

>docker run postgres
C:\Program Files\Docker\Docker\resources\bin\docker.exe: Error response from daemon: No command specified.
See 'C:\Program Files\Docker\Docker\resources\bin\docker.exe run --help'.

Although it can be successfully imported as an image, the image cannot be used.

To find out what's going on, let's first look at the difference between image package and container package:

You can see from the above that Postgres on the right- export.tar The content of is the file directory of a linux system, which is supposed to be a linux image. And postgres-save.tar What's in it? Click to open a folder:

In fact, it is a hierarchical file system. The Docker image is actually superimposed by such layers of files. The upper layer files will overwrite the lower layer files with the same name. If postgres-save.tar The layers of files in are merged together, which is basically postgres-export.tar Content of. Due to postgres-save.tar There are many duplicate files in each layer, which also explains why postgres-save.tar It's better than postgres-export.tar More than 100 M larger.

docker load must load a hierarchical file system, while postgres-export.tar Cannot load because it does not have such a structure.

docker import just copies the files in the tar package, so no matter what the file structure in the tar package is, it can be loaded in, so it can load postgres-save.tar . But postgres-save.tar It's not a valid operating system image, so when I try to start the container with a different image, the container doesn't start.

Let's take a look at the help of docker import:

Usage:  docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image

Options:
-c, –change list Apply Dockerfile instruction to the created image
–help Print usage
-m, –message string Set commit message for imported image

It seems similar to docker commit:

Usage:  docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes

Options:
-a, --author string Author (e.g., "John Hannibal Smith
<hannibal@a-team.com>")
-c, --change list Apply Dockerfile instruction to the created image
–help Print usage
-m, --message string Commit message
-p, --pause Pause container during commit (default true)

It is found that both docker import and docker commit have -- change and -- message options. We can understand docker import as copying external files to form a single file system image, while docker commit is to submit the current changes to a single file system and then overlay them on the original image.

Tags: Docker Linux git Ubuntu

Posted on Sat, 27 Jun 2020 23:43:41 -0400 by NewBob