The difference between docker save and docker export
Both docker save and docker export can export image packages. At first glance, there seems to be little difference. Aiming at this problem, this paper tries to find out what the functions of docker save and docker export are? What application scenarios are applicable?
*Note: users can use docker load to import image storage files to the local image library, or docker import to import a container snapshot to the local image library. The difference between the two is that the container snapshot file will discard all history and metadata information (that is, only the snapshot state of the container at that time), while the mirror storage file will save the complete record and have a large volume. In addition, metadata information such as labels can be reassigned when importing from the container snapshot file.
The docker versions tested in this article are as follows. It is not guaranteed that all versions of docker can reproduce the results of this article.
>docker version Client: Version: 17.07.0-ce-rc1 API version: 1.31 Go version: go1.8.3 Git commit: 8c4be39 Built: Wed Jul 26 05:19:44 2017 OS/Arch: windows/amd64 Server: Version: 17.07.0-ce-rc1 API version: 1.31 (minimum version 1.12) Go version: go1.8.3 Git commit: 8c4be39 Built: Wed Jul 26 05:25:01 2017 OS/Arch: linux/amd64 Experimental: true
Besides, I'm Windows on bash Inside operation docker，Some commands such aslsNot at all windows Command, if you want to repeat my experiment, please change to the corresponding one windows Command.
The command line interface of docker is designed elegantly. You can view the help of many commands directly by adding -- help.
The help of docker save is as follows:
>docker save --help Usage: docker save [OPTIONS] IMAGE [IMAGE...] Save one or more images to a tar archive (streamed to STDOUT by default) Options: --help Print usage -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
Packaged images Tar contains two images: postgres:9.6 and mongo:3.4.
Although the command line parameter requires that image 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 8 June 26-14:40 b.tar -rwxrwxrwx 1 root root 277886464 8 June 26-14:41 c.tar
As like as two peas, you can see that b.tar and c.tar are exactly the same. This shows that if docker save specifies container, docker save will save the image behind the container.
Load the packaged image and use docker load, for example:
docker load -i images.tar
The above command will load 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 if your application uses docker compose Multiple image combinations arranged by YML, but the client server you want to deploy cannot be connected to the Internet. At this time, you can use docker save to package the images used, then copy them to the client server and load them with docker load.
Check the help of docker export as usual:
>docker export --help Usage: docker export [OPTIONS] CONTAINER Export a container's filesystem as a tar archive Options: --help Print usage -o, --output string Write to a file, instead of STDOUT
As can be seen from the help, docker export is used to package the file system of the container. For example:
docker export -o postgres-export.tar postgres
Container must be specified for docker export, but neither image nor container can be specified like docker save.
Load the packaged container and use docker import, for example:
docker import postgres-export.tar postgres:latest
As can be seen from the above command, the container imported by docker import will become an image instead of being restored to a container.
Another point is that docker import can specify IMAGE[:TAG], indicating 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 stripped and assigned to the new image. The operation can only be performed through the original IMAGE ID.
The application scenario of docker export is mainly used to create 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 basic development environment.
The difference between docker save and docker export
Summarize the difference between docker save and docker export:
- docker save saves the image and docker export saves the container;
- docker load is used to load the image package and docker import is used to load the container package, but both will be restored to the 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 readers can know as long as they carefully look at the official documents. In this section, I'll talk about what's not on the document.
Both docker load and docker import can import tar packages as images. I can't help wondering whether docker load can import the container package of docker export and docker import can import the image package of docker save?
Start the test and prepare the following two documents:
>ls -al -rwxrwxrwx 1 root root 271760384 8 December 26:15 postgres-export.tar -rwxrwxrwx 1 root root 398292480 8 December 26:13 postgres-save.tar
Postgres export Tar is the container package exported through docker export, Postgres save Tar is the image package saved through docker save, both of which are based on postgres:9.6 image. From the file size, you can intuitively find that Postgres export Tar is obviously better than Postgres save Tar is less than 100 M.
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 container packages.
So, conversely, 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
WTF, it succeeded!!!
Don't panic. 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, this image cannot be used.
To find out what's going on, let's first look at the difference between image package and container package:
From the above, you can see the Postgres export on the right The content of tar is a file directory of linux system. I guess it is a linux image. And Postgres save What's in tar? Click a folder to see:
It's actually a layered file system. Docker image is actually superimposed by such layers of files. The files in the upper layer will overwrite the files with the same name in the lower layer. If Postgres save All layers of files in tar are merged together, basically Postgres export Contents of tar. Due to Postgres save There are many duplicate files in the layers of tar, which also explains why Postgres save Tar is better than Postgres export Tar is more than 100 M.
docker load must load a hierarchical file system, and Postgres export Tar does not have such a structure and cannot be loaded.
docker import only 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 be loaded into Postgres save tar. But Postgres save Tar is not a valid operating system image, so when I try to start the container with a changed image, the container does not 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 to be 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 an image with only one layer of file system, while docker commit is to submit the current changes to one layer of file system and then superimpose them on the original image.