6
votes

I'm newbie with Docker and I'm trying to better understand the Volumes topic. Here I see that:

  • Volumes are initialized when a container is created. If the container’s base image contains data at the specified mount point, that existing data is copied into the new volume upon volume initialization. (Note that this does not apply when mounting a host directory.)
  • Data volumes can be shared and reused among containers.
  • Changes to a data volume are made directly.
  • Changes to a data volume will not be included when you update an image.
  • Data volumes persist even if the container itself is deleted.
  • Data volumes are designed to persist data, independent of the container’s life cycle. Docker therefore never automatically deletes volumes when you remove a container, nor will it “garbage collect” volumes that are no longer referenced by a container.

Which is very clear, except for this:

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

and I'm really struggling having a better understanding of this. Can anyone provide me some more clear overview, possibly with some basic example?

Thanks!

2

2 Answers

7
votes

Volumes live outside of your container's filesystem. They are mounted at runtime but data in them does not live in the container. Let's take an example:

j@host $ docker volume create --name my-data

This creates a volume (no containers yet) called my-data. Now I create a new container and mount this volume inside my container at /inside/data.

j@host $ docker run -it -v my-data:/inside/data --name container1 alpine:3.3 sh

Now I'm in my shell inside my container, so I create a new file inside the folder /inside/data.

root@container1 $ cd /inside/data && touch my-file

Now /inside/data isn't really in my container filesystem, it's a volume that lives outside of the container, that is just mounted in. If I stop my container, and _don't mount that volume back in, my file isn't there.

root@container1 $ exit
j@host $ docker run -it --name container2 alpine:3.3 sh
root@container2 $ ls /inside/data
ls: /inside/data: No such file or directory
root@container2 $ exit

In fact, even the folder isn't there! Because I didn't mount anything at that location. I'm using volumes, so my data is not persisted in the container. So how do I find it again? Well it is persisted in the volume (my-data). Let's take a look at it by mounting it to another container (I don't need to mount it at the same point, I'm going to use something different).

j@host $ docker run -it -v my-data:/different/folder --name container3 alpine:3.3 sh
root@container3 $ ls /different/folder
my-file
root@container3 $ exit

OK so I can get that data and mount it around to different containers. But where does the data in a volume actually live? Well on my host filesystem. We can check by doing:

j@host $ docker volume inspect my-data
[
    {
        "Name": "my-data",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/my-data/_data",
        "Labels": {},
        "Scope": "local"
    }
]

OK, so it tells me where on my host machine that volume is located, let's take a look at what's in there (we need sudo because it's owned by root).

j@host $ sudo ls /var/lib/docker/volumes/my-data/_data
my-file

And there's the file!

1
votes

I think it's trying to say if the data volume is changed by other process (it could be changed from other container or other system), the changes will not be included / recorded when you building / updating your docker image, which is very obvious.