Keep Your Data Safe: A Guide to Persistent Storage in Docker and Podman!
image credits: educba.com

Keep Your Data Safe: A Guide to Persistent Storage in Docker and Podman!

A container's data stays as long as the container is running. Once you stop the container, all the data created by that container will be lost. But what if you are using stateful applications (apps that require permanent storage) such as databases inside containers? How can you make containers' data fail safe so that the data will be there even if the container stopped, restarted or crashes?

This guide will work well both on docker and podman - podman is a container management tool developed by redhat but its underlying architecture also uses the same containerd and runC runtime environments utilized by docker.

If you want to learn more about internal architecture of a container management tool just like docker, read my other article HERE

So any commands mentioned here for docker will also work for podman the same way - you just need to replace the word docker with podman. e.g We can view running containers by using this command:

In docker:

docker ps        

In podman:

podman ps        

Okay, back to the topic. For simplicity, I will explain it in terms of docker, but since you know podman works the same way, so you can understand it in poman's perspective if you are working with that .

Docker provides two mechanisms for storing persistent data: Volumes and Bind mounts. Lets explore them.

Bind Mounts and Docker Volumes:

Just like my previous article, I have created a visual representation to understand the concept easily. It's recommended to keep it opened. VIEW it HERE

Bind Mount:

Bind mount is a technique in which you bind a directory on your host system with a directory inside the container. In the diagram, I am creating an httpd container and using the concept of bind mount to keep the data persistent.

You can always open the full diagram by clicking on image

By using the -v switch with docker run command, I am successfully able to bind /home/data directory on the host system with /usr/local/apache2 directory inside the container. This way, any data produced by container inside the /usr/local/apache2 directory will automatically become available in the /home/data directory on host system and vice versa.

This will work best for developers since bind mounting your source code directory with container will allows you to test changes inside container without building the docker image again and again.

Volumes:

In the case of bind mount, you must have a directory created already and then you attach it to a directory inside container. But in case of volumes, you don't have to create a directory first, look at the command below:

docker run -v vol1:/usr/local/apache2 httpd        

When docker runs this httpd container, it will automatically create a volume with name vol1 and attach it with respective directory inside container.

A volume is also just another directory created at path /var/lib/docker/volumes. Do not confuse it with disk volumes.

Using volumes have some advantages that bind mounts lack. Docker has built in commands that only works with volumes. For example you can use the following command to view all the created volumes:

docker volume ls        

You can also create volumes in advance without attaching them to containers, and you can attach them later. Use this command:

docker volume create vol2        

This will create a new volume with name vol2. Verify if it's created using docker volume ls command.

Sharing Volumes between multiple containers:

One volume can be shared between multiple containers. Just run the second container with the same volume attached, that was previously attached with another container.

docker run -v vol1:/usr/local/apache2 httpd:2.4        

We have started another container with version 2.4 of httpd but attached the same vol1 to this container.

Making Read-Only volumes:

There may be a scenario when you want to attach a volume to container but you don't want the container to make modifications to data inside volume. Just add the ro field in your command.

docker run -v vol2:/usr/local/apache2:ro httpd:latest        

Now the container will be able to read but can't make modifications.

This is useful in scenarios when you have a volume shared with multiple containers but you want only some specific containers to make changes to data.

Preserving data from a running container:

Bind mounts and volumes are useful only when you are creating a new container from image, but what if you have a container that is already in running state and has not bind mounted and no volume attached to it?

Just use docker cp command:

docker cp 55e:/usr/local/apache2  /apache_data        

Tips:

  • Which container is using a specific volume?

docker ps --filter volume=vol1        

This will view all the containers attached to vol1.

  • Create a new container and attach volume, that was previously attached to another container. You don't have to remember the name of that volume. just use --volume-from

docker run -d --volumes-from 55e httpd:2.4        

This will attach the volume from container id 55e to the new container.

  • Find out which volume is used by a specific container using docker inspect.

docker inspect f3c        

and scroll to the "Mounts" section. This container is using vol1.

Conclusion:

Bind mounts, docker volumes and docker cp command come in handy when yiu want to copy data pr make it preserved outside of containers. Do you have any other tips to share regarding keeping containers' data persistent? Don't forget to share in comments.



Muhammad Ateeb Aslam

DevOps Engineer | Certified in CyberSecurity (isc2) |

10mo
Like
Reply

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics