Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between VOLUME declaration in Dockerfile and -v as docker run parameter

Could some one help me to understand the difference between:

VOLUME command in Dockerfile (image building layer)

and

-v parameter when issuing docker run-v/xyz/bla command (container building layer).

-v parameter is for me clear, it simply exposes a directory from the host to the container and vice versa, but how does VOLUME in Dockerfile behave differently?

like image 772
Mohammed Noureldin Avatar asked Oct 20 '16 19:10

Mohammed Noureldin


People also ask

What is the purpose of the volume parameter in a docker Run command?

The purpose of using Docker volumes is to persist data outside the container so it can be backed up or shared. Docker volumes are dependent on Docker's file system and are the preferred method of persisting data for Docker containers and services.

What is the difference between run and ENTRYPOINT in Dockerfile?

They both specify programs that execute when the container starts running, but: CMD commands are ignored by Daemon when there are parameters stated within the docker run command. ENTRYPOINT instructions are not ignored but instead are appended as command line parameters by treating those as arguments of the command.

What are the two types of docker volumes?

Docker volumes are used to persist data from within a Docker container. There are a few different types of Docker volumes: host, anonymous, and, named. Knowing what the difference is and when to use each type can be difficult, but hopefully, I can ease that pain here.

What is the difference between ENV and Arg in Dockerfile?

ENV is for future running containers. ARG for building your Docker image. ¶ ENV is mainly meant to provide default values for your future environment variables.


2 Answers

The -v parameter and VOLUME keyword are almost the same. You can use -v to have the same behavior as VOLUME.

docker run -v /data 

Same as

VOLUME /data 

But also -v have more uses, one of them is where map to the volume:

docker run -v data:/data # Named volumes docker run -v /var/data:/data # Host mounted volumes, this is what you refer to -v use, but as you can see there are more uses, 

So the question is: what is the use of VOLUME in a Dockerfile?

The container filesystem is made of layers so writing there, is slower and limited (because the fixed number of layers) than the plain filesystem.

You declare VOLUME in your Dockerfile to denote where your container will write application data. For example a database container, its data will go in a volume regardless what you put in your docker run.

If you create a docker container for JBoss and you want to use fast filesystem access with libaio yo need to declare the data directory as a VOLUME or JBoss will crash on startup.

In summary VOLUME declares a volume regardless what you do in docker run. In fact in docker run you cannot undo a VOLUME declaration made in Dockerfile.

Regards

like image 169
Carlos Rafael Ramirez Avatar answered Oct 07 '22 22:10

Carlos Rafael Ramirez


In a nutshell

The VOLUME [PATH] instruction inside a Dockerfile is equivalent to

$ docker run -v $(docker volume create):[PATH] [IMAGE_NAME] 

Detailed explanation

The container filesystem is made of layers so writing there is slower and limited (because the fixed number of layers) than the plain filesystem.

Using volumes in Docker is primarily less a matter of speed than a matter of data persistance independet from a container's life cycle. Mounting volumes from a faster disk will obviously improve performance, but Docker's default behavior for VOLUME is to create a named volume on the host system with little to no speed improvements compared to the container's writable layer.

-v parameter is for me clear, it simply exposes a directory from the host to the container and vice versa

While this is partly true, -v can also be used to mount named volumes into your Docker container instead of a directory. This little detail is important in order to understand what VOLUME does. An example:

$ docker volume create my_volume $ docker run -v my_volume:[PATH] [IMAGE_NAME] 

Here a volume named my_volume was created. It behaves as would expect from a 'normal' mount. Any changes to [PATH] inside the container will be persisted in this volume. The difference is that Docker manages the volume's location, so that you don't need to worry (it is /var/lib/docker/volumes/my_volume/_data in case you're interested). Why would you want this? You could have a test database. While you don't need direct access to the files, you might want to save the current state to mount it into other database containers.

The VOLUME [PATH] instruction basically saves the above instructions into the image's metainformation. So everytime you start a container from this image, Docker knows that you want to persist [PATH] in a volume and takes care of that.

like image 42
stepf Avatar answered Oct 07 '22 22:10

stepf