Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a docker best practice to use volume for the code?

Tags:

docker

The VOLUME instruction should be used to expose any database storage area, configuration storage, or files/folders created by your docker container. You are strongly encouraged to use VOLUME for any mutable and/or user-serviceable parts of your image.

will you store your code in volume?

Such as your jar files. It could be a little convenient to deploy the application without rebuilding the image.
Are there any considerations if storing the code in volume? like performance, security or others.

like image 737
Cypine Avatar asked May 19 '17 02:05

Cypine


People also ask

What is the reason for using volumes in Docker?

While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker. Volumes have several advantages over bind mounts: Volumes are easier to back up or migrate than bind mounts. You can manage volumes using Docker CLI commands or the Docker API.

Do I need Docker volumes?

Volumes are the preferred way to persist data in Docker containers and services. Some use cases for volumes include: Sharing data among multiple running containers. If you don't explicitly create it, a volume is created the first time it is mounted into a container.

What are the advantages of Docker volumes?

Advantages of Docker Volumes Managing volumes can done from the Docker CLI or Docker API. They are easy to backup, restore, and migrate. Sharing data among containers is relatively simpler.


2 Answers

I don't recommend using a VOLUME statement inside the Dockerfile for anything with current versions of docker (current being any version of docker since the introduction of named volumes). Including a VOLUME command has multiple downsides, including:

  • possible inability to change contents at that location of the image with any later steps or child images (this behavior appears to be different with different scenarios and different versions of docker)
  • potential to create volumes with just a hash for the name that clutter up the docker volume ls output and are very difficult to find and reuse later if you needed the data inside
  • for your changing code, if you place it in a volume and recreate your container from a new version of the image, the volume will still have the old copy of your code unless you update that volume yourself (the key feature of volumes is persistent data that you don't want to keep between iterations)

I do recommend putting your data in a volume that you define on the docker run command line or inside a docker-compose.yml. Volumes defined there can have a name or map back to a path on the docker host. And you can make any folder or file a volume without needing to define it in the Dockerfile. Volumes defined at this step doesn't impact the image, allowing you to extend an image without being locked out of making changes to a directory.

For your code, it is a common best practice to inject code with a volume if it is interpreted (e.g. javascript) or already compiled (e.g. a jar file) during application development. You would define the volume on the container (not the Dockerfile), and overlay the code or binaries that were also copied into the image using the same filenames. This allows you to rapidly iterate in development without frequently rebuilding the image. Depending on the application, you may be able to live reload the code, otherwise, a container restart should be all that's needed to see the latest change. And once development is finished, you rebuild the image with your current code and ship that to someone that can use it without needing the volume mount for the code.

I've also blogged about my concerns with volumes inside of Dockerfiles if you'd like to see more details on this.

like image 123
BMitch Avatar answered Sep 23 '22 01:09

BMitch


You say:

It could be a little convenient to deploy the application without rebuilding the image.

Instead of that, it has a lot of advantages to encapsulate your application version inside an image build. You can easily deploy your app only deploying the image, so the fact that you use a volume for app code leads you to orchestrate some other deployment method to update that volume too.

And you have to (eventually) match the jar version with the proper image version.

Regarding security or performance, I don't think that there are special considerations.

Anyway, it is not a common approach to use volumes for that. And as @BMitch say, using VOLUME inside Dockerfile is some tricky.

like image 39
Robert Avatar answered Sep 26 '22 01:09

Robert