What is the purpose of VOLUME in Dockerfile?
Asked Answered
H

4

171

What are the differences and use-cases between:

  • The docker volume create command
  • The docker run -v /path:/host_path
  • The VOLUME entry in the Dockerfile file

Specifically, I don't understand what happens if you combine the VOLUME entry with the -v flag.

Handcar answered 15/1, 2016 at 11:3 Comment(1)
A
112

A volume is a persistent data stored in /var/lib/docker/volumes/...

  • You can either declare it in a Dockerfile, which means each time a container is started from the image, the volume is created (empty), even if you don't have any -v option.

  • You can declare it on runtime docker run -v [host-dir:]container-dir.
    Combining the two (VOLUME + docker run -v) means that you can mount the content of a host folder into your volume persisted by the container in /var/lib/docker/volumes/...

  • docker volume create creates a volume without having to define a Dockerfile and build an image and run a container. It is used to quickly allow other containers to mount said volume.

If you had persisted some content in a volume, but since then, deleted the container (which by default does not delete its associated volume, unless you are using docker rm -v), you can re-attach said volume to a new container (declaring the same volume).

See "Docker - How to access a volume not attached to a container?".
With docker volume create, this is easy to reattach a named volume to a container.

docker volume create --name aname
docker run -v aname:/apath --name acontainer
...
# modify data in /apath
...
docker rm acontainer

# let's mount aname volume again
docker run -v aname:/apath --name acontainer
ls /apath
# you find your data back!

Why volumes were introduced in the first place?

Docker volumes were introduced primarily to solve the challenge of data persistence and data sharing in containerized environments.
In the world of Docker, containers are ephemeral and lightweight, meaning they can be created, started, stopped, and destroyed with ease, and they are designed to be stateless.
However, applications often need to store data permanently, access configuration files, or share data between different containers or between containers and the host system. That is where Docker volumes come into play.

Volumes provide a mechanism to persist data generated by and used by Docker containers.
Unlike the container's writable layer, which is tightly coupled to the container's lifecycle and gets destroyed when the container is removed, volumes are managed by Docker and are designed to exist independently of containers.
That means data in volumes survives container restarts and can be securely shared among multiple containers. And volumes are platform-independent, which simplifies data migration and backup processes.
See "Docker Engine / Storage / Manage data in Docker"

volumes

Additionally, volumes address performance and security concerns. Since they are stored outside the container's filesystem, they offer improved I/O performance, especially important for database storage or heavy read/write operations. They also provide a safer way to handle sensitive data, as volumes can be more securely isolated from the core container filesystem.

Amylolysis answered 15/1, 2016 at 11:35 Comment(9)
Let's say you use a Dockerfile with VOLUME and the -v /path:/host_path/ flag. The content of the VOLUME will be overrided by the the content of /host_path/?Handcar
Thanks to you @VonC, I think I get it :) And if you do a docker volume create --name my_volume followed by a docker run --volume-from my_volume, how do you know where the mountpoint will be?Handcar
@Handcar no mount point (meaning nothing mounted from the host, beside the native empty /var/lib/docker/volume). The path of the volume is in the my_volume metadata: https://mcmap.net/q/80897/-how-do-you-list-volumes-in-docker-containersAmylolysis
I understand that there is no mountpoint on the host side. But within the running container lauched with docker run ..., how can I write into a file stored on the my_volume volume? I do not know the... path? of the volume inside my running container because I defined nothing? I hope I'm clear enough, because I'm definitely not sure of my vocable :-/Handcar
@Handcar the docker volume create --name aname creates a named volume: You assign a container path on runtime: docker run -v aname:/apath: that container now has a volume attached to it, mounted to its /apath folder. I have rewritten the answer to make that clear.Amylolysis
If you want to use standalone volumes docker volume create ... but still want them to persist on the host, you can use a plugin such as: github.com/cwspear/local-persist (disclaimer: that's my repo)Lieabed
You do not need the VOLUME in Dockerfile for docker run -v.Burger
I don't see how does this answer the question regarding the purpose of volumes in Docker. It does give some idea about what volumes are, but it doesn't really delve into why they were introduced in the first place.Scintilla
@MehdiCharife Good point, thank you for your feedback. I have edited the answer to address your comment.Amylolysis
B
26

VOLUME instruction becomes interesting when you combine it with volumes-from runtime parameter.

Given the following Dockerfile:

FROM busybox
VOLUME /myvolume

Build an image with:

docker build -t my-busybox .

And spin up a container with:

docker run --rm -it --name my-busybox-1 my-busybox

The first thing to notice is you will have a folder in this image named myvolume. But it is not particularly interesting since when we exit the container the volume will be removed as well.

Create an empty file in this folder, so run the following in the container:

cd myvolume
touch hello.txt

Now spin up a new container, but share the same volume with my-busybox-1:

docker run --rm -it --volumes-from my-busybox-1 --name my-busybox-2 my-busybox

You will see that my-busybox-2 contains the file hello.txt in myvolume folder.

Once you exit both containers, the volume will be removed as well.

Burger answered 5/10, 2019 at 12:59 Comment(1)
The volumes will be deleted because they are anonymous volumes AND you started the containers with the --rm option. I think it might works mentioning it. If you didn't start a container with --rm, you can still remove container and its anonymous volumes with docker rm -v my-container.Darlinedarling
P
6
  1. Specifying VOLUME in Dockerfile makes sure the folder is to be treated as a volume(i.e., outside container) at runtime, as opposed to be a regular directory inside the container. Note the performance and accessibility implications;
  2. If having forgot to specify -v in docker run command line, the above is still true. It's just the volume name becomes anonymous. But there are still ways to access or recover data from such anonymous volumes.
Painkiller answered 20/4, 2021 at 19:7 Comment(1)
"Note the performance and accessibility implications." Can you elaborate?Scintilla
E
1

Using MYSQL from docker hub:

Running the below command as an example:

$ docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

The -v /my/own/datadir:/var/lib/mysql part of the command mounts the /my/own/datadir directory from the underlying host system as /var/lib/mysql inside the container, where MySQL by default will write its data files.

Therefore, a directory that persists when the container is killed is mounted is available that also provided higher performance for some operations like databases actions.

Encamp answered 26/12, 2021 at 8:33 Comment(1)
In addition to your example, this shows how flexible volumes are. Author of an image simply tells what should live outside the container by using VOLUME, and a user can: do nothing and let Docker create an anonymous volume, or tell Docker to mount it to physical location on a disk, or mount it to some pre-defined Docker volume. That's awesome, because author of the image doesn't know where users want to keep their data. Besides, when you forget to mount the volume, do some work, and kill the container, there's no "oops, data lost", because it can be retrieved from the anonymous volume.Fukuoka

© 2022 - 2024 — McMap. All rights reserved.