User Tools

Site Tools


docker:containers:share_data_between_docker_containers

Docker - Containers - Share data between docker containers

Docker Volumes can be created and attached in the same command that creates a container, or they can be created independent of any containers and then attached later.

There are a number of different ways to share data between containers.


Creating an Independent Volume

Docker's 1.9 onwards allows a volume to be created without it relating to any particular container:

docker volume create --name DataVolume1

The name is displayed, indicating that the command was successful.

Output
DataVolume1

To make use of the volume, we'll create a new container from the Ubuntu image, using the –rm flag to automatically delete it when we exit. We'll use -v to mount the new volume. -v requires the name of the volume, a colon, then the absolute path to where the volume should appear inside the container. If the directories in the path don't exist as part of the image, they'll be created when the command runs. If they do exist, the mounted volume will hide the existing content.

docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu

Write some data to the volume:

echo "Example1" > /datavolume1/Example1.txt

Because we used the –rm flag, the container will be automatically deleted when we exit. The volume, however, will still be accessible.

exit

Verify the volume is present on the system with docker volume inspect:

docker volume inspect DataVolume1

result:

Output
[
    {
        "Name": "DataVolume1",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/datavolume1/_data",
        "Labels": null,
        "Scope": "local"
    }
]

WARNING: The data on the host can also be accessed at the path listed as the Mountpoint.

Avoid altering this as it can cause data corruption if applications or containers are unaware of changes.


Start a new container and attach DataVolume1:

docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu
cat /datavolume1/Example1.txt

displays:

Output
Example1

Exit the container.

exit

In this example, we created a volume, attached it to a container, and verified its persistence.


Creating a Volume that Persists when the Container is Removed

Create a volume at the same time as the container, delete the container, then attach the volume to a new container.

docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu

Write some data to the volume:

echo "Example2" > /datavolume2/Example2.txt
cat /datavolume2/Example2.txt

Output:

Example2

Exit the container:

exit

Restart it - the volume will mount automatically.

docker start -ai Container2

Verify that the volume has indeed mounted and our data is still in place:

cat /datavolume2/Example2.txt

Output

Example2

Exit and clean up.

exit

Docker won't allow a volume to be removed if it's referenced by a container. Try anyway:

docker volume rm DataVolume2

The message tells us that the volume is still in use and supplies the long version of the container ID:

Output:

Error response from daemon: Unable to remove volume, 
volume still in use: remove DataVolume2: volume is in use - 
[719f98391ecf1d6f0f053ffea1bbd84cd2dc9cf6d31d5a4f348c60d98392804c]

Use the ID to remove the container:

docker rm 719f98391ecf1d6f0f053ffea1bbd84cd2dc9cf6d31d5a4f348c60d98392804c

Output:

719f98391ecf1d6f0f053ffea1bbd84cd2dc9cf6d31d5a4f348c60d98392804c

Removing the container won't affect the volume. Check it's still present on the system:

docker volume ls

Output:

DRIVER              VOLUME NAME
local               DataVolume2

Remove the volume:

docker volume rm DataVolume2

In this example, we created an empty data volume at the same time that we created a container.


Creating a Volume from an Existing Directory with Data

If a volume is created at the same time a container is created and the path to a directory is provided that contains data in the base image, that data will be copied into the volume.

Create a container and add the data volume at /var, a directory which contains data in the base image:

docker run -ti --rm -v DataVolume3:/var ubuntu

All the content from the base image's /var directory is copied into the volume, and we can mount that volume in a new container. This time, rather than relying on the base image's default bash command, we'll issue our own ls command, which will show the contents of the volume without entering the shell:

docker run --rm -v DataVolume3:/datavolume3 ubuntu ls DataVolume3

DataVolume3 has a copy of the contents of the base image's /var directory:

Output:

backups
cache
lib
local
lock
log
mail
opt
run
spool
tmp

It's unlikely that we would want to mount /var/ in this way, but this can be helpful if we've crafted our own image and want an easy way to preserve data.


Sharing Data between Multiple Docker Containers

To have multiple containers attached to the same data volume.

WARNING: Attaching multiple containers to the same data volume is relatively straightforward, but there's one critical caveat: at this time, Docker doesn't handle file locking.

If you need multiple containers writing to the volume, the applications running in those containers must be designed to write to shared data stores in order to prevent data corruption.


Create Container4 and DataVolume4

Use docker run to create a new container named Container4 with a data volume attached:

docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu 

Create a file and add some text:

echo "This file is shared between containers" > /datavolume4/Example4.txt

Exit the container.

exit

This returns us to the host command prompt, where we'll make a new container that mounts the data volume from Container4.


Create Container5 and Mount Volumes from Container4

docker run -ti --name=Container5 --volumes-from Container4 ubuntu
cat /datavolume4/Example4.txt

Output:

This file is shared between containers.

Append some text from the second container:

echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt

Exit the container:

exit

Check that the data is still present to Container4.


View Changes Made in Container5

Check for the changes that were written to the data volume by Container5 by restarting Container4:

docker start -ai Container4
cat /datavolume4/Example4.txt
cat /DataVolume4/Example4.txt

Output:

This file is shared between containers. Both containers can write to DataVolume4

Now that we've verified that both containers were able to read and write from the data volume, we'll exit the container:

exit

Remember that Docker doesn't handle any file locking, so applications must account for the file locking themselves.

It is possible to mount a Docker volume as read-only to ensure that data corruption won't happen by accident when a container requires read-only access by adding :ro.


Start Container 6 and Mount the Volume Read-Only

Once a volume has been mounted in a container, rather than unmounting it like we would with a typical Linux file system, we instead create a new container mounted the way we want it and, if needed, remove the previous container.

To make the volume read-only, we append :ro to the end of the container name:

docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu

Check the read-only status by trying to remove our example file:

rm /datavolume4/Example4.txt

Output:

rm: cannot remove '/datavolume4/Example4.txt': Read-only file system

Exit the container and clean up our test containers and volumes:

exit

Clean up our containers and volume:

docker rm Container4 Container5 Container6
docker volume rm DataVolume4

In this example, we've shown how to share data between two containers using a data volume and how to mount a data volume as read-only.

docker/containers/share_data_between_docker_containers.txt · Last modified: 2020/07/15 09:30 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki