TL;DR: The "export" command gives you a flattened tarball of a container's file system, and it can't be used to recreate a running container alone as information is dropped (eg: RUN, USER, etc). The "save" command saves an image of layers, and also things like RUN and USER commands. If you want to move images from one host to another without a Docker registry, use "save" and "load", not "export" and "import".
docker run
or docker create
).You can not "import an exported container" because information is lost, for example what command to run on startup. Let's go ahead and export a container:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
minperl latest c265df3173ad 9 months ago 67MB
minperl-builder latest 25287931efbf 9 months ago 1.01GB
perl 5.32.0-buster 2c9e278d16c6 9 months ago 859MB
Create an instance of an image (a specific container called "minperl0"):
docker create --name minperl0 minperl:latest
Here the "--all" is required because the container is not running, and "ls" by default hides stopped containers.
$ docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
658d6314bdef minperl:latest "/usr/bin/perl -Iloc…" About a minute ago Created minperl0
$ docker export minperl0 > minperl0.tar
$ docker container rm 658d6314bdef
$ tar -tf minperl0.tar
.dockerenv
app.psgi
cpanfile
cpanfile.snapshot
...
When I did this .dockerenv
was an empty file. As you can see it is simply a tarball of a directory - there is no information there about what command to run, what ports are exposed, what user to run as, etc - that has all been lost.
Now if you want to take that tarball and move it somewhere else, you have to treat it as an image. You load the image and then create/run containers off that.
$ docker import minperl0.tar minperl2:latest
Here I gave the repository name as "minperl2" to avoid a clash with the original "minperl". Now you can create containers from this image:
$ docker create --name minperl20 minperl2:latest
Error response from daemon: No command specified
Errp! Makes sense right? Because we exported a container and not an image we lost information about the entry point. Docker can not create a container because it doesn't know what command is supposed to be run.
I guess you could say that "export" + "import" is kind of a way of flattening your image into a single layer. Using "save" will preserve those layers and also preserve the RUN command etc. So "export" is actually kinda useless...
Grokking this means you will understand for realz the difference between images and containers.