Skip to content

docker export and docker import


Sometimes you don’t need to distribute a complete Docker image.

You only need to take the filesystem of a container, move it somewhere else, and turn that filesystem into a new image.

That’s exactly what docker export and docker import are for.

The key idea is:

Container
    |
    | docker export
    v
Filesystem archive
    |
    | docker import
    v
New image

Notice that the starting point is a container, not an image.

That single detail explains most of the difference between export/import and the save/load pair we’ll see next.

Start with a Container

Let’s use a small Alpine container.

Run:

docker container run -d \
  --name export-demo \
  alpine:latest \
  sh -c 'echo "Hello from the container" > /message.txt && sleep 300'

The container now has a file that we created:

Container
└── /message.txt

Check it:

docker container exec export-demo cat /message.txt

You should get:

Hello from the container

Now we have something worth exporting.

Export the Container

docker container export works with a stopped container too. The container doesn’t need to be running because Docker is exporting its filesystem, not asking the container’s process to do anything.

Running container  ──┐
                     ├── docker container export ──> archive
Stopped container  ──┘

Run:

docker container export export-demo --output container.tar

Docker creates:

container.tar

The important thing to understand is what that archive represents.

It represents the container’s filesystem.

export-demo
     |
     | docker container export
     v
container.tar
     |
     └── filesystem contents

It is not a normal Docker image archive.

It does not preserve the image’s complete metadata and history.

We’ll make that distinction very explicit when we compare export with save.

What Exactly Are We Exporting?

Think about the container as a filesystem:

Container filesystem

/
├── bin/
├── etc/
├── usr/
├── var/
├── message.txt
└── ...

docker container export takes that filesystem and packages it into an archive.

Conceptually:

Container filesystem
        |
        v
     TAR archive

That’s why the command is called export.

You’re exporting the container’s filesystem.

Import It as an Image

Now turn the archive back into a Docker image:

docker image import container.tar exported-demo:1.0

The command creates:

exported-demo:1.0

Check your images:

docker image ls

You should see the new image.

The complete flow was:

Alpine image
     |
     v
Container
     |
     | export
     v
container.tar
     |
     | import
     v
exported-demo:1.0

The interesting part is that the final image doesn’t have to keep the original image name.

We created a completely new image name:

exported-demo:1.0

Run the Imported Image

Now create a container from the imported image:

docker container run --rm \
  exported-demo:1.0 \
  cat /message.txt

You should see:

Hello from the container

The file survived the export/import process because it was part of the container’s filesystem.

So:

Original container
      |
      | /message.txt
      v
Filesystem archive
      |
      v
Imported image
      |
      v
New container
      |
      | /message.txt
      v
"Hello from the container"

What Gets Preserved?

The safest mental model is:

docker export preserves the container’s filesystem contents.

So files inside the container’s writable filesystem are included.

But Docker image information is a different matter.

Things such as:

  • image history
  • image layers
  • original image metadata
  • the original image’s build history

are not preserved as an ordinary Docker image through export.

This is why an exported container filesystem should not be thought of as “the original image packed into a file.”

It is a filesystem archive.

What About the Container’s Configuration?

This is another important limitation.

Runtime settings such as:

network mode
published ports
container name

are not captured as the complete container configuration.

The archive contains files.

It doesn’t contain the complete recipe for recreating the original container.

Think:

export
  ↓
"What files were inside this container?"

not:

export
  ↓
"How was this container originally configured?"

That distinction becomes very important in the save vs export comparison.

Volumes Are Different

There is another important boundary.

A volume mounted into the container is not part of the container’s writable filesystem.

For example:

Container
├── writable filesystem
│     └── /message.txt
│
└── mounted volume
      └── /data

If you export the container, the mounted volume’s contents are not included as part of the exported container filesystem.

That’s because the data belongs to the volume, which is a separate Docker resource.

This is another reason to think carefully about what export actually means:

Export the container’s filesystem, not every piece of storage the container happens to use.

docker export vs docker container export

You’ll see both forms:

docker export ...

and:

docker container export ...

The second is the modular command form we’ve been using throughout these lessons.

They refer to the same Docker operation.

For this project, we’ll continue using:

docker container export

because it makes the resource being operated on explicit.

Useful export Options

The most useful option for our examples is:

--output

For example:

docker container export export-demo \
  --output container.tar

Instead of writing the archive to standard output, Docker writes it directly to the specified file.

This is much more convenient for normal file-based distribution.

Without --output, you can redirect the output yourself, but that’s less clear for a beginner:

docker container export export-demo > container.tar

Both can produce an archive, but --output directly expresses what we’re trying to do.

Import Options

The corresponding operation is:

docker image import container.tar exported-demo:1.0

The general form is:

docker image import SOURCE REPOSITORY[:TAG]

So:

container.tar
    ↓
exported-demo:1.0

You can also import from standard input, but for a beginner workflow, an explicit archive file is much easier to understand.

You Can Add Metadata During Import

docker image import can also add image metadata.

For example, you can specify a command:

docker image import \
  --change 'CMD ["cat", "/message.txt"]' \
  container.tar \
  exported-demo:1.0

Now the imported image has a default command.

This is useful because the filesystem archive itself doesn’t contain the full Docker image configuration.

The --change option lets you apply supported Dockerfile-style configuration changes while importing.

For this lesson, you don’t need to memorize every possible --change value.

Just remember:

export
  ↓
filesystem only

import
  ↓
filesystem → image
           + optional configuration changes

The Whole Process

Let’s put everything together:

    flowchart LR
    C["Container<br/>export-demo"] -->|"docker container export"| T["container.tar<br/>filesystem archive"]
    T -->|"docker image import"| I["exported-demo:1.0<br/>Docker image"]
    I -->|"docker container run"| N["New container"]
  

The important thing is what happens at each boundary:

Container
    |
    | export
    v
Filesystem archive
    |
    | import
    v
Image

There is no direct:

Image
   |
   | export
   v
archive

export starts with a container.

Likewise:

archive
   |
   | import
   v
Image

import produces an image.

When Is Export / Import Useful?

This workflow is useful when you specifically want a container’s filesystem as a portable archive.

For example:

Container filesystem
        |
        v
      .tar
        |
        | copy to another machine
        v
    docker import
        |
        v
      Image

It can be useful for:

  • moving a container filesystem between machines
  • creating a simple filesystem-based image
  • extracting a container’s filesystem into an archive
  • situations where image history and layer information aren’t important

But it is not usually the first choice for distributing a properly built application image.

For that, docker save and docker load preserve much more of the image itself.

That’s our next topic.

Clean Up

Remove the test container:

docker container rm -f export-demo

Remove the imported image:

docker image rm exported-demo:1.0

Remove the archive:

rm container.tar

If you’re using Windows PowerShell instead of a Unix-like shell, remove the file with:

Remove-Item container.tar

What You Should Remember

Don’t memorize the commands first. Remember the direction:

CONTAINER
    |
    | export
    v
FILESYSTEM ARCHIVE
    |
    | import
    v
IMAGE

Or the short version:

Export takes a container’s filesystem out. Import turns that filesystem archive into an image.

And the most important warning:

export is not a way to save a complete Docker image.

It throws away image-layer/history information and focuses on the container’s filesystem.

That’s exactly why Docker also has another pair of commands:

docker image save
docker image load

Those operate on images, not container filesystems.

We’ll look at those next.

Last updated on