How to specify source and target for a VOLUME in Dockerfile?

Viewed 9663

I want to mount a VOLUME in a Dockerfile specifying both source (host) and destination (container) paths.

This operation can be done with docker-compose.yml in this way:

volumes:
  - /path/source/on/host:/path/destination/on/container

How can I do the same thing with a Dockerfile?

3 Answers

You can't mount a VOLUME in a Dockerfile specifying both source (host) and destination (container) paths.

This is because this idea does not fit the basic concept that Docker image is portable and independent of host.

What you can use is the parameter

-v /path/source/on/host:/path/destination/on/container

when you run your container.

For a running container the first step is commit your container

docker commit <id> new container_name

Second

docker run -v /path/source/on/host:/path/destination/on/container container_name

From the documentation

The docker run command initializes the newly created volume with any data that exists at the specified location within the base image. For example, consider the following Dockerfile snippet:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

This Dockerfile results in an image that causes docker run to create a new mount point at /myvol and copy the greeting file into the newly created volume. The file was copied from the container to the volume. There was no host path (i.e. location on the computer you are running docker on) used at all.

Some points to keep in mind

Docker volumes might not hold any data when they are created (if created in isolation with docker volume create), but their "seed" data initially comes from a container that has write access to that volume, which copies its destination to the source at mount time.

Configuration property names source and destination always make sense for bind mounts, where there is an already existing location on the host machine that is copied and injected into the container at creation time, but it only becomes intuitive for volumes after the initial data seeding has occurred - for instance, if you mount an existing volume on a container that has read only access to it, then there is no source or destination.

Since Docker manages the location of volumes (so on a Mac their location is inside the Linux Virtual Machine on which Docker runs - you wont find them by browsing your Mac HD) and considers them to be largely used for persisting application state, there are many restrictions on their use in Dockerfiles, for instance in Windows if any build steps change the data within the volume after it has been declared, those changes will be discarded.

You can backup, restore and migrate data volumes from (i.e. that are mounted on) pre-existing containers. See the documentation below for more on this.

Further Reading

General introduction to volumes: https://docs.docker.com/storage/volumes/

How to specify volumes in the Dockerfile: https://docs.docker.com/engine/reference/builder/#volume

How to specify volumes in compose.yaml file: https://docs.docker.com/compose/compose-file/#volumes

Related