arrow left
Back to Developer Education

How to Share Data Between Docker Containers

How to Share Data Between Docker Containers

A container is a way of making a program run independently when moved from one environment to another. Containerization, on the other hand, is the process of packaging containers to make it easier to scale them out and enhance their portability. <!--more--> A Docker container enables you to develop and run your applications from your environment quickly. You can learn more about Docker from here.

Prerequisites

To get started, we have to install Docker on our system. Check out this amazing article on Getting Started with Docker.

If you're not using Ubuntu be sure to review the official documentation on how to install Docker on your Operating System environment.

Note that we will be using Ubuntu 20.04 in this tutorial.

Creating an independent volume

Docker volumes are system files that are attached to containers and help to persist data. Docker volumes are also vital when one wants to share data across different containers.

Let's get started.

We'll use the docker volume create command to create a volume without associating it to any container.

Let's create a volume named NewVol1:

docker volume create NewVol1

If we list our output, we can see the created volume:

docker volume ls
DRIVER    VOLUME NAME
local     NewVol1

Next, we need to set up a new container from the Ubuntu image. We use the --rm flag to delete the container when the user exits. The -v flag mounts the new volume.

The name of the volume must be specified followed by a colon and an absolute path, as shown below:

docker run -ti --rm -v NewVol1:/newvol1 ubuntu

The snippet below shows you how to write data to the Docker volume in a container.

root@77a92a143828:/# echo "Example1" > /newvol1/Example1.txt

We exit the root using the code snippet below:

root@77a92a143828:/# exit

To check if our volume still resides in our environment we use docker volume inspect:

docker volume inspect NewVol1

The output is:

[
    {
        "CreatedAt": "2021-05-12T20:20:24+03:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/NewVol1/_data",
        "Name": "NewVol1",
        "Options": {},
        "Scope": "local"
    }
]

The output is in a JSON array format. It shows the timestamp of the inspection. The Driver and Scope are both in our local system.

However, the Labels and Options are empty since we did not specify them. The Mountpoint shows the path that the volume resides in. The name property indicates the volume we are inspecting.

Next, let's start a new container and attach NewVol1:

docker run -ti --rm -v NewVol1:/newvol1 ubuntu

You can check the contents, as shown below:

docker run -ti --rm -v NewVol1:/newvol1 ubuntu
root@b4a69fffc60a:/# cat /newvol1/Example1.txt
Example1
root@b4a69fffc60a:/# exit
exit

Creating a volume from an existing directory with data

In this step, we will create a volume inside a container with data.

At the /var path, let's set up a container and add a Docker volume:

docker run -ti --rm -v NewVol2:/var ubuntu
root@976fbd71c0a7:/# exit
exit

Note that contents from the /var directory are duplicated in the Docker volume. We also attach the volume to the latest container and exit the current directory.

We are using the ls command as opposed to the default bash for launching the shell:

docker run --rm -v NewVol2:/newvol2 ubuntu ls newvol2
backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

The newvol2 index duplicates the components in the /var directory.

Using this method to attach /var/ helps in rendering the image.

Sharing data between multiple Docker containers

More often than not we'll want various containers to mount to similar Docker volume. However, Docker doesn't handle file locking. To write various containers to the volume, the current environment of the containers should be a device that supports shared data stores.

Creating Container3 and DataVolume3

We use docker run to set up a new container called Container3 as below:

docker run -ti --name=Container3 -v NewVol3:/newvol3 ubuntu

We then add some text to a new file as shown below:

root@1ef4d68f08b2:/# echo "Shared container file" > /newvol3/Example3.txt
root@1ef4d68f08b2:/# exit
exit

We then exit the container and navigate to the host terminal where we create a new container that attaches data volume from Container3.

Create Container4 and attach volumes from Container3

Let's attach Container3 to the newly created Container4 as shown below:

docker run -ti --name=Container4 --volumes-from Container3 ubuntu

The data consistency is checked as shown:

root@d19c4e150495:/# cat /newvol3/Example3.txt
Shared container file
root@d19c4e150495:/#

At this point, let's append some texts from Container4 then exit the container:

root@d19c4e150495:/# echo "Both containers can write to NewVol3" >> /newvol3/Example3.txt
root@d19c4e150495:/# exit
exit

Subsequently, we'll check if our data is still present in Container3.

Container4 changes

We can check for changes in the Docker volume by refreshing Container3:

docker start -ai Container3

The commands below confirm if all containers were able to read and write from the Docker volume and then exit the environment:

root@1ef4d68f08b2:/# cat /newvol3/Example3.txt
Shared container file
Both containers can write to NewVol3
root@1ef4d68f08b2:/# exit
exit

Start Container5 and attach the volume read-only

If a container has been mounted by a data volume, we don't unmount it as a typical Linux file. We set up a new container and make the volume read-only.

Appending the :ro flag at the end of the container name makes it read-only, as shown below:

docker run -ti --name=Container5 --volumes-from Container3:ro ubuntu

We test the read-only prominence by trying to omit the file we created:

root@9b1678a2d548:/# rm /newvol3/Example3.txt
rm: cannot remove '/newvol3/Example3.txt': Read-only file system
root@9b1678a2d548:/# exit
exit

The command below clears our test containers and volumes:

docker rm Container3 Container4 Container5
docker volume rm NewVol3

Conclusion

In this tutorial, we have learned how to create an independent Docker volume that persists data when a container is deleted. It also facilitates data sharing across different containers.

The file locking mechanism reduces data corruption. Lastly, we have also learned how to mount a shared volume and make it read-only.

Other resources


Peer Review Contributions by: Wanja Mike

Published on: Jun 7, 2021
Updated on: Jul 12, 2024
CTA

Start your journey with Cloudzilla

With Cloudzilla, apps freely roam across a global cloud with unbeatable simplicity and cost efficiency