Skip to main content

Docker Volumes and Persistent Storage

Introduction

By now, you have learned how to build and run Docker containers, and even create your own custom images. However, you've likely noticed that any data written inside a running container disappears once the container stops or is removed. This stateless nature is by design, but many real-world applications require data persistence: databases, logs, user uploads, and more.

Docker volumes are the primary mechanism Docker provides for persistent storage, decoupling your data from the lifecycle of containers. In this lesson, you will learn how to use Docker volumes to persist, share, and manage data across containers.


Why Persistent Storage Matters

Containers are ephemeral—when they're deleted, their filesystem changes are lost. Consider these scenarios:

  • A database running in a container loses all its data when the container is removed.
  • Uploaded files to a web app are gone after the app restarts.
  • Application logs aren’t available for troubleshooting after a crash.

Persistent storage solves these problems by storing data outside the container's writable layer.


Docker Storage Options

Docker provides multiple ways to manage persistent data:

  1. Volumes (recommended): Managed by Docker, stored outside container filesystem.
  2. Bind mounts: Mount specific host directories/files into the container.
  3. tmpfs mounts: Store data in host memory, not persisted after restart (not covered in detail here).

We will focus primarily on volumes, but will also introduce bind mounts for completeness.


Understanding Docker Volumes

What is a Docker Volume?

A volume is a directory (or file) stored outside the container’s Union File System, managed by Docker. Volumes are independent of the container lifecycle—deleting a container does not delete its volumes.

Key characteristics:

  • Can be shared and reused among containers.
  • Easier to back up or migrate than bind mounts.
  • Managed entirely by Docker.

Creating and Listing Volumes

Create a volume:

docker volume create mydata

List all volumes:

docker volume ls

Inspect a volume:

docker volume inspect mydata

Using Volumes in Containers

Mount a volume into a container using the -v or --mount flag.

Using -v (short syntax):

docker run -d \
--name my_nginx \
-v mydata:/usr/share/nginx/html \
nginx
  • mydata is the name of the volume.
  • /usr/share/nginx/html is the path inside the container.

Using --mount (long syntax):

docker run -d \
--name my_nginx \
--mount type=volume,source=mydata,target=/usr/share/nginx/html \
nginx

Both methods achieve the same result. The long syntax is more explicit and flexible.


Bind Mounts vs. Volumes

A bind mount links a specific file or directory on the host to the container.

docker run -d \
--name my_nginx \
-v /home/user/website:/usr/share/nginx/html \
nginx

Differences:

AspectVolumeBind Mount
Managed by DockerYesNo
Storage locationDocker-managed directoryAny host directory/file
Backup/migrationEasy (via Docker CLI)Manual
Use caseApplication data, databasesSource code, configs

Use volumes for application data; use bind mounts mainly for development or config injection.


Common Use Cases for Docker Volumes

  1. Databases: Persisting database files (/var/lib/mysql, /var/lib/postgresql/data).
  2. Application uploads: User-generated files in web apps.
  3. Logs: Retaining application/service logs outside containers.
  4. Sharing data between containers: E.g., sharing a socket file.

Example: Persisting MySQL Data

docker volume create mysql_data

docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-v mysql_data:/var/lib/mysql \
mysql:8
  • MySQL data files are now stored in the volume mysql_data.
  • Stopping or removing the container keeps your data safe.

Removing Volumes

Volumes are not deleted when you remove a container by default.

Delete a volume explicitly:

docker volume rm mydata

Or remove all unused volumes:

docker volume prune

Sharing Volumes Between Containers

Multiple containers can access the same volume. This is useful for:

  • Web/app and worker containers sharing uploaded files.
  • Log aggregation.

Example:

docker run -d --name web -v shared_data:/app/data mywebapp
docker run -d --name worker -v shared_data:/app/data myworker

Backing Up and Restoring Volumes

Backup:

docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine \
tar czf /backup/mydata.tar.gz -C /data .

Restore:

docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/mydata.tar.gz -C /data

Common Mistakes and Pitfalls

  • Confusing Volumes with Bind Mounts: Bind mounts reference host paths; volumes are managed by Docker.
  • Accidentally Deleting Volumes: docker volume rm or docker volume prune is irreversible.
  • Mounting Volumes Over Existing Data: Data in the container at the mount point is hidden by the volume.
  • Permissions Issues: The container user may not have write permissions to the volume, especially when using custom images.

Summary

  • Volumes provide persistent, Docker-managed storage decoupled from the container lifecycle.
  • Use volumes for databases, uploads, logs, and shared data.
  • Volumes are safer and easier to manage than bind mounts for most persistent storage needs.
  • Always check mount points and permissions to avoid data loss or access issues.

Quiz

  1. What happens to data written inside a container if you do not use a volume or bind mount?

    Answer: The data is lost when the container is removed, as it is stored in the container's ephemeral writable layer.

  2. How can you list all Docker volumes on your system?

    Answer: By running docker volume ls.

  3. Which is the recommended method for persisting database files in Docker: volumes or bind mounts?

    Answer: Volumes are recommended for persisting database files.

  4. What is a common mistake when mounting a volume into a container at a path that already contains data?

    Answer: The existing data at that path inside the container becomes hidden by the mounted volume.

  5. True or False: Removing a container will always delete its associated volumes.

    Answer: False. Volumes persist even after the container is removed unless they are explicitly deleted.