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
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.
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:
- docker save saves image, and docker export saves container;
- 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;
- docker load cannot rename the loaded image, while docker import can specify a new name for the image.
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 <firstname.lastname@example.org>") -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.