Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse the same volume in Docker when restarting a container?

Tags:

docker

I have a Dockerfile that states at the end a Volume like so

VOLUME /data

Now when I build and run this container I indeed get a new volume created and mounted at /data.
That's very good but I would like to be able to stop this container and then run it again and make sure the very same volume with its data is mounted back.

How can I achieve that?
Ideally the same command would create the volume if it does not exist already, and reuse it if it already exists.

like image 590
Bastian Avatar asked Sep 03 '15 15:09

Bastian


People also ask

What happens when you restart a docker container?

docker restart does two things: It does the equivalent of docker stop . It sends SIGTERM to its primary process (only); if that doesn't terminate within 10 seconds, it sends SIGKILL. If the primary process still has children, they also get forcibly terminated.

Can two docker containers use the same volume?

Multiple containers can run with the same volume when they need access to shared data. Docker creates a local volume by default. However, we can use a volume diver to share data across multiple machines. Finally, Docker also has –volumes-from to link volumes between running containers.


2 Answers

If you want to persist your data beyond the lifetime of your container, you need to create the volume outside of the container. One option is to create a "data volume container", as described in the documentation:

docker create -v /data --name my-data busybox /bin/true

This creates a container (named my-data). It's based on the busybox image, but because we're using create rather than run we don't actually start anything. This container only exists to provide a volume to other containers.

We can then access that volume using the --volumes-from option to docker run when we start another container:

docker run --volumes-from my-data ...

Now you have a volume that will still exists after the container exists, and will persist as long as your my-data container is not deleted.

Alternately, you can simply mount a host directory on /data in your container, as in:

docker run -v /path/on/host:/data ...

This options is also described in the docs I linked to above.

like image 162
larsks Avatar answered Oct 24 '22 10:10

larsks


The larsks answer was the way to follow (or at least the workaround) before the advent of named volumes.
Now just use named volumes that is much more simple and standard.

That's very good but I would like to be able to stop this container and then run it again and make sure the very same volume with its data is mounted back.

If you stop a running container (with docker stop id) and that then you start it (with docker start id), the volume associated to the container will be still around without the need to use a named volume or any trick because it still uses the same container.
The problem of volume that doesn't persist occurs between distinct runs (docker run fooImageName) for a same image.

Anonymous and named volumes

Specifying a volume has two forms : anonymous and named.
If we don't specify a name for that, the volume on the host cannot be reused in next container running because that is anonymous (but by using two distinct containers : one for the application and another for the data with the anonymous volume as in the larsks answer). So as the volume is anonymous, Docker creates a new volume on the host for every container run for a same image.

To use a named volume, when we run the container we just need to prefix a name (whatever we want, that it is a logical name) to the file/directory mounted in the container.
For example with a volume declared in dockerfile :

VOLUME /data

we could start the container as :

docker run -v my-volume:/data myImage

At the first run, the volume is created. And then for any next run, we need just to specify still the named volume my-volume to reuse that volume.

Here is the interesting part of the documentation (emphasis is mine) :

Choose the -v or --mount flag

...

  • -v or --volume: Consists of three fields, separated by colon characters (:). The fields must be in the correct order, and the meaning of each field is not immediately obvious.
    • In the case of named volumes, the first field is the name of the volume, and is unique on a given host machine. For anonymous volumes, the first field is omitted.
    • The second field is the path where the file or directory are mounted in the container.
    • The third field is optional, and is a comma-separated list of options, such as ro.

As alternative if for some reasons you need to create the volume without starting the container you can use the docker volume command.
You can read in the volumes documentation :

Create and manage volumes

Unlike a bind mount, you can create and manage volumes outside the scope of any container.

Create a volume:

$ docker volume create my-vol

We would use it exactly like previously :

docker run -v my-volume:/data myImage
like image 10
davidxxx Avatar answered Oct 24 '22 10:10

davidxxx