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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With