A Comprehensive Guide to Docker Volumes

Chidozie C. Okafor
9 min readApr 5, 2023

--

Docker volumes are an essential feature for managing and persisting data in Docker containers. Volumes allow users to store data outside of the container’s filesystem, making it easy to share data between containers and ensure that data is not lost when containers are removed or updated. In this comprehensive guide, we will discuss the concept of Docker volumes, their types, and how to use them effectively in various scenarios.

Table of Contents:

  1. Understanding Docker Volumes
  2. Types of Docker Volumes
  • Bind Mounts
  • Named Volumes
  • Anonymous Volumes

3. Creating and Managing Docker Volumes

  • Creating Volumes with Docker CLI
  • Creating Volumes with Docker Compose

4. Backup and Restore Strategies for Docker Volumes

5. Sharing Data between Containers

6. Cleaning Up Unused Volumes

7. Best Practices for Working with Docker Volumes

8. Conclusion

1. Understanding Docker Volumes:

Docker volumes are a method of storing data generated or used by a Docker container. Docker manages volumes, which are separate from the container’s filesystem, making them less prone to data loss and allowing for more efficient data sharing between containers. Volumes can be used to store database files, application configurations, and user-uploaded content, among other things.

Assume you’re throwing a super fun party at your house for your friends and want to make it an unforgettable experience. You begin organizing everything and realize you must consider the setup, decorations, and food.

Docker acts as your party planner, and the Docker containers act as individual party elements.

Docker Containers: A dance floor (container A), a dining area (container B), and a bar are required (container C). Each of these containers serves a distinct purpose and is separate from the others. These containers can be started, stopped, or replaced as needed.

Docker Volumes: Now, consider the actual items that complete the party, such as the disco ball, party hats, and food. These items can be shared and moved around, but they must be stored and accessed somewhere. This is where Docker volumes come into play.

A Docker volume, in our amusing illustration, is like a magical refrigerator where you can store all of your party supplies. This refrigerator has a unique feature in that it can connect to any of the containers (dance floor, dining area, and bar) to supply the items they require.

You can have multiple magical refrigerators (volumes), each with its own function. As an example:

  • music_volume stores all the cool tunes for the dance floor.
  • food_volume holds the delicious snacks for the dining area.
  • drinks_volume is filled with refreshing beverages for the bar.

Backup and Restore: You decide to move your party to a larger house one day. You don’t want to lose all of your fantastic party supplies that you’ve amassed over time. So you load everything from the magical refrigerators into “Backup Boxes,” which function similarly to portable storage units.

When you move into your new home, you discover new magical refrigerators (volumes) and unpack the items from the Backup Boxes, relocating your party supplies.

Automatic Backup: To ensure that none of your valuable party supplies are ever lost, you hire a diligent gnome named “Backup Buddy.” Backup Buddy transfers the contents of your magical refrigerators into Backup Boxes and stores them in a secure location every night. If anything goes wrong, you’ll always have a backup of your party supplies on hand.

Docker volumes act as magical refrigerators, storing and managing the essential elements for your party (application). They can be shared, backed up, and restored, ensuring that your containers are fully equipped to deliver an unforgettable experience. So, let the festivities begin!

To create a volume

docker run -d -p 3306:3306 --name=mysql_container -e MYSQL_ROOT_PASSWORD=my-secret-pw -v mysql_data:/var/lib/mysql mysql:latest

This command creates a MySQL container and adds a named volume mysql data to the container’s /var/lib/mysql directory, ensuring that the data is preserved even if the container is removed or updated.

2. Types of Docker Volumes:

There are three main types of Docker volumes: bind mounts, named volumes, and anonymous volumes.

Bind Mounts:

Bind mounts map a directory or file on the host system to a directory or file within the container. This volume type is useful for transferring configuration files or source code between the host and container.

In this example, we will bind mount the host directory /home/user/my project to the container’s /app directory.

docker run -d -p 80:80 -v /home/user/my_project:/app nginx:latest

Named Volumes:

Docker creates and manages named volumes, which provide a convenient way to persist data across container restarts and removals. Named volumes are more portable than bind mounts and can be easily shared between containers.

docker volume create my_data
docker run -d -p 80:80 -v my_data:/var/log/nginx nginx:latest

In this example, we will create a named volume called my data and use it to store logs in a Nginx container.

Anonymous Volumes:

Anonymous volumes are similar to named volumes in that they are not given a name. When a container is started without specifying a volume name or bind mount, they are created automatically.

Let’s create an anonymous volume for an Nginx container.

docker run -d -p 80:80 -v /var/log/nginx nginx:latest

3. Creating and Managing Docker Volumes:

Creating Volumes with Docker CLI:

The Docker command-line interface can be used to create and manage volumes (CLI). The commands below demonstrate common tasks:

  • Create a named volume: docker volume create my_volume
  • List volumes: docker volume ls
  • Inspect a volume: docker volume inspect my_volume
  • Remove a volume: docker volume rm my_volume

Creating Volumes with Docker Compose:

Docker Compose is a tool that allows you to define and run multi-container Docker applications. In a docker-compose.yml file, you can create and manage volumes, making it simple to define your application’s entire infrastructure in a single file.

version: "3"
services:
web:
image: my_web_app:latest
volumes:
- .:/app
db:
image: postgres:latest
volumes:
- db_data:/var/lib/postgresql/data

volumes:
db_data:

We will define a named volume db data for a PostgreSQL container and a bind mount for a web application in this docker-compose.yml file.

4. Backup and Restore Strategies for Docker Volumes:

Backups should be performed on a regular basis to ensure data integrity and recovery in the event of a disaster. To backup and restore Docker volumes, you can use a variety of methods, such as creating a.sql file or a.tar.gz archive.

Backup

docker run --rm -v db_data:/volume -v $(pwd):/backup alpine tar cvf /backup/db_data_backup.tar /volume

Restore

docker run --rm -v db_data:/volume -v $(pwd):/backup alpine tar xvf /backup/db_data_backup.tar -C /volume

5. Sharing Data between Containers:

Docker volumes make data sharing between containers simple. To share configuration files, application data, or other resources between multiple containers, use named volumes or bind mounts.

As an example, we’ll share a named volume app data between two containers so that they can both access the same data.

docker volume create app_data
docker run -d --name container1 -v app_data:/shared_data my_image:latest
docker run -d --name container2 --volumes-from container1 my_image:latest

6. Cleaning Up Unused Volumes:

Unused volumes eat up disk space and cause clutter. To remove all unused volumes, use the `docker volume prune` command.

docker volume prune

7. Best Practices for Working with Docker Volumes:

  • Use named volumes: Using named volumes makes managing and referencing your volumes easier. Named volumes are simple to backup, restore, and share between containers.
  • Separate data and containers: Keep the data in your application in volumes and the containers stateless. This allows you to update, replace, or scale containers while maintaining data integrity.
  • Use Docker Compose: Docker Compose makes it easier to manage containers, volumes, and networks. For easy management and version control, define your volumes in a docker-compose.yml file.
  • Use the correct volume driver: Docker supports a variety of volume drivers, including local, nfs, and third-party plugins. Select the volume driver that best meets your needs and performance expectations.
  • Backup volumes on a regular basis: To avoid data loss, backup your volumes on a regular basis.To ensure that you always have a recent backup of your data, use automatic backup tools or scripts.
  • Remove unused volumes: Clean up unused volumes on a regular basis to free up disk space. To remove volumes that are no longer in use by any container, use the docker volume prune command.
  • Use .dockerignore: To exclude unnecessary files and directories from your Docker context, use a .dockerignore file. This helps to reduce image size and improve build times.
  • Protect your volumes: Set appropriate permissions and ownership to restrict access to your volumes. When mounting a volume, use the:ro flag to make it read-only, reducing the risk of data modification by accident.

Bonus Point: Automating the backup process

Shell scripts, cron jobs, and Docker commands can be used to automate the backup process for Docker volumes. For example example, we’ll write a shell script that backs up a Docker volume automatically and schedule it with a cron job.

  1. Create a shell script backup_docker_volume.sh:
#!/bin/bash

# Variables
VOLUME_NAME="db_data"
BACKUP_DIR="/backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILENAME="backup_${VOLUME_NAME}_${TIMESTAMP}.tar.gz"

# Create the backup directory if it doesn't exist
mkdir -p "${BACKUP_DIR}"

# Use Docker to run a temporary container with the volume attached
# The container will create a compressed archive of the volume's contents
docker run --rm \
-v "${VOLUME_NAME}:/volume_data" \
-v "${BACKUP_DIR}:/backup" \
busybox tar -czf "/backup/${BACKUP_FILENAME}" -C "/volume_data" .

echo "Backup of ${VOLUME_NAME} created: ${BACKUP_DIR}/${BACKUP_FILENAME}"

This script makes a compressed archive of the volume’s contents using the busybox image. Replace VOLUME_NAME with the name of the volume you want to backup and BACKUP_DIR with the backup directory you want to use.

2. Make the script executable:

chmod +x backup_docker_volume.sh

3. Schedule the script using a cron job:

crontab -e

Then, to schedule the backup script, add a new line. To run the script every day at 3 a.m., for example, add the following line:

0 3 * * * /path/to/backup_docker_volume.sh >> /path/to/backup.log 2>&1

Replace `/path/to/backup_docker_volume.sh` with the script’s actual path. The output of the script will be redirected to a log file named `/path/to/backup.log` by this cron job. Replace this path with the location of your desired log file.

Save your changes and exit the crontab editor. The backup script will now run on the specified schedule automatically.

You can ensure that your data is secure and up to date by automating the backup process for Docker volumes, lowering the risk of data loss and simplifying the overall backup process.

How to use the backed up data

To use the backed-up data, you must first restore it to a Docker volume from the backup archive. Here’s how to restore data from a backup archive to a Docker volume step by step:

  1. Identify the backup file you want to restore:

Find the backup file you want to restore, typically a .tar.gz file created by the backup process, such as backup_db_data_20230101_030000.tar.gz.

2. Create a new Docker volume (optional):

If you want to restore the data to a new volume or you have removed the original volume, create a new volume using the following command:

docker volume create new_volume_name

3. Restore the data to the Docker volume:

Run a temporary container with the target volume and the backup directory mounted, and then extract the contents of the backup archive to the target volume:

docker run --rm \
-v new_volume_name:/volume_data \
-v /path/to/backup_directory:/backup \
busybox tar -xzf "/backup/backup_db_data_20230101_030000.tar.gz" -C "/volume_data"

Replace new_volume_name with the name of the volume you want to restore the data to, /path/to/backup_directory with the path to the directory containing the backup file, and backup_db_data_20230101_030000.tar.gz with the name of the backup file.

4. Verify the restored data:

You can verify that the data has been restored correctly by running a temporary container and inspecting the contents of the restored volume:

docker run --rm -it \
-v new_volume_name:/volume_data \
busybox ls -l /volume_data

5. Use the restored data:

Now that you have restored the data to a Docker volume, you can use it by attaching the volume to a new or existing container. Update the docker run or docker-compose.yml file to use the restored volume.

If you are using Docker Compose, update the volumes section for the desired service:

services:
db:
...
volumes:
- new_volume_name:/var/lib/mysql

After restoring the data, you can start your containers as usual, and they will use the restored data from the backup archive.

To further your understanding of Docker volumes, I highly recommend the informative resource “Guide to Docker Volumes — How to Use Volumes with Examples.” This useful resource, which includes practical examples and expert tips, is ideal for delving deeper into seamless container management. Check it out!!!

If you’ve enjoyed this content and are eager to stay updated on the latest insights, tips, and tricks, be sure to follow me on social media! Connect with me on Twitter, GitHub, and LinkedIn

--

--

Chidozie C. Okafor
Chidozie C. Okafor

Written by Chidozie C. Okafor

Software Engineer & Backend Magician 🎩 | Python, Rust | TypeScript, Node.js | Golang | Kafka & GRPC

No responses yet