4

I am trying to capture the state of a docker container as an image, in a way that includes files I have added to a volume within the container. So, if I run the original container in this way:

$ docker run -ti -v /cookbook ubuntu:14.04 /bin/bash
root@b78f3599d936:/# cd cookbook
root@b78f3599d936:/cookbook# touch foo.txt

Now, if I either export, or commit the container as a new docker image, and then run a container from the new image, then the file, foo.txt is never included in the /cookbook directory.

My question is whether there is a way to create an image from a container in a way that allows the image to include file content within its volumes.

nwinkler
  • 52,665
  • 21
  • 154
  • 168
rezaloo
  • 41
  • 2

4 Answers4

2

Well, by putting the changes in a volume, you're excluding them from the actual container. The documentation for docker export includes this:

The docker export command does not export the contents of volumes associated with the container. If a volume is mounted on top of an existing directory in the container, docker export will export the contents of the underlying directory, not the contents of the volume.

Refer to Backup, restore, or migrate data volumes in the user guide for examples on exporting data in a volume.

This points to this documentation. Please follow the steps there to export the information stored in the volume.

You're probably looking for something like this:

docker run --rm --volumes-from <containerId> -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /cookbook

This would create a file backup.tar with the contents of the container's /cookbook directory and store it in the current directory of the host. You could then use this tar file to import it in another container.

Community
  • 1
  • 1
nwinkler
  • 52,665
  • 21
  • 154
  • 168
2

whether there is a way to create an image from a container in a way that allows the image to include file content within its volumes?

No, because volume is designed to manage data inside and between your Docker containers, it's used to persist and share data. What's in image is usually your program(artifacts, executables, libs. e.g) with its whole environment, building/updating data to image does not make much sense.

And in docs of volumes, they told us:

  • Changes to a data volume will not be included when you update an image.

Also in docs of docker commit:

  • The commit operation will not include any data contained in volumes mounted inside the container.
shizhz
  • 11,715
  • 3
  • 39
  • 49
1

Essentially, there are three ways to do persistence in Docker:

  1. You can keep files in a volume, which is a filesystem managed by Docker. This is what happens in your example: because the /cookbook directory is part of a volume, your file does not get commited/exported with the image. It does however get stored in the volume, so if you remount the same volume in a different container, you will find your file there. You can list your volumes using docker volume ls. As you can see, you should probably give your volumes names if you plan to reuse them. You can mount an existing volume, or create a new one, if the name does not exist, with

    docker run -v name:/directory ubuntu

  2. You can keep files as part of the image. If you commit the container, all changes to its file hierarchy are stored in the new image except those made to mounted volumes. So if you just get rid of the -v flag, your file shows up in the commit.

  3. You can bind mount a directory from the host machine to the container, by using the -v /hostdir:/targetdir syntax. The container then simply has access to a directory of the host machine.

KarlSt
  • 176
  • 3
0

Docker commit allows you to create an image from a container and its data (mounted volumes will be ignored)

herm
  • 14,613
  • 7
  • 41
  • 62