Skip to main content

Command Palette

Search for a command to run...

Docker Volumes and Bind Mounts Explained with Hands-On

Published
7 min read

Introduction

One of the most confusing topics for Docker beginners is data persistence.

You run a container, everything works fine, you create files or even store application data.
Then you stop or remove the container — and suddenly all the data is gone.

This is not a bug.
This is how Docker containers are designed.

In this blog, we will clearly understand:

  • Why containers lose data

  • Why Docker Volumes exist

  • What Bind Mounts are

  • Differences between Volumes and Bind Mounts

  • How to create, inspect, list, and delete volumes

  • How to mount volumes into containers (hands-on)

  • Why --mount is preferred over -v

  • Why volumes cannot be deleted while in use

This article follows Docker’s official documentation and real-world practices.


1️⃣ Problem Statement: Why Do We Need Volumes?

Why Containers Lose Data

Docker containers are ephemeral by nature.

This means:

  • A container’s filesystem exists only while the container exists

  • When a container is removed, its writable layer is deleted

Example:

docker run -it ubuntu bash
touch hello.txt
exit

docker run -it ubuntu ls

👉 hello.txt is gone. The file does not exist because each container starts with a fresh filesystem.

This is intentional. Containers are designed to be:

  • Reproducible

  • Replaceable

  • Stateless by default


Why This Is a Real Problem

Real applications must store data:

  • Databases

  • Logs

  • User uploads

  • Application state

If data disappears with containers, applications become unusable.

👉 Docker Volumes solve this problem.


2️⃣ Introduction to Docker Bind Mounts

What Is a Bind Mount?

A Bind Mount directly connects:

  • A directory on the host machine

  • To a directory inside the container

Docker does not manage this data. Docker only provides access to the host path; the host filesystem remains the source of truth.


Bind Mount Hands-On (Quick and Practical)

In this example, we create a directory on the host machine and mount it into a container using a bind mount.


Step 1: Prepare Data on the Host

mkdir bind_data
echo "Hello from host" > bind_data/index.html
cd bind_data

This creates a directory on the host and adds a sample file that will be served by the container.


Step 2: Run a Container with a Bind Mount

docker run -d -p 8080:80 -v $(pwd):/usr/share/nginx/html nginx

This is a single command.

What this command does:

  • docker run → creates and starts a container

  • -d → runs the container in detached (background) mode

  • -p 8080:80 → maps host port 8080 to container port 80

  • -v $(pwd):/usr/share/nginx/html → bind-mounts the current host directory into the container

  • nginx → image used to create the container


Step 3: Verify the Bind Mount

curl http://localhost:8080

Output:

Hello from host

This confirms:

  • The container is running

  • Nginx is serving content

  • The file is being read directly from the host filesystem


Step 4: Prove Instant File Sync

echo "Updated from host" > index.html

Check again:

curl http://localhost:8080

Output:

Updated from host

No container restart is required.
This instant update is the defining behavior of bind mounts.


Key Takeaways

  • Bind mounts directly expose host files to the container

  • Docker does not manage bind mount data

  • Changes on the host are instantly reflected in the container

  • Best suited for development and testing, not production


When Bind Mounts Are Used

Bind mounts are commonly used for:

  • Local development

  • Live code editing

  • Debugging

  • Accessing logs

They are not recommended for production.


3️⃣ Understanding Docker Volumes

What Is a Docker Volume?

A Docker Volume is storage that:

  • Is managed by Docker

  • Lives outside the container lifecycle

  • Persists even after containers are deleted

On Linux, volumes are stored internally at:

/var/lib/docker/volumes/

⚠️ You should never manually modify this directory.


4️⃣ Creating and Exploring Docker Volumes (Hands-On)

Create a Volume

docker volume create my_volume

This command:

  • Creates only a volume

  • Does NOT create a container

  • Does NOT create an image


List All Volumes

docker volume ls

Inspect a Volume

docker volume inspect my_volume

By default, Docker uses the local volume driver, which stores data on the host filesystem.
This shows:

  • When the volume was created

  • The storage driver (usually local)

  • The mount location

  • Whether it is in use

This is extremely useful for debugging and audits.


5️⃣ Advantages of Volumes Over Bind Mounts

FeatureBind MountVolume
Managed by Docker❌ No✅ Yes
Depends on host path✅ Yes❌ No
Portable❌ No✅ Yes
Secure by default❌ No✅ Yes
Production-ready❌ No✅ Yes
Backup & restoreManualEasy

👉 This is why Docker officially recommends volumes for persistent data.


6️⃣ Lifecycle of Docker Volumes

Important Concept

Volumes and containers have independent lifecycles.

Volume Lifecycle

  1. Volume is created

     docker volume create my_volume
    
  2. Volume is mounted to a container

  3. Container stops or is removed

    • Volume still exists
  4. Volume is deleted only manually

     docker volume rm my_volume
    

7️⃣ Mounting a Volume to a Container (Simple & Practical)

In this step, we mount a Docker volume into a real application container to demonstrate how volumes provide persistent storage independent of containers.

Run a Container with a Docker Volume

docker run -d --name nginx-volume-demo --mount source=my_volume,target=/usr/share/nginx/html nginx:latest

This single command:

  • Creates and starts an Nginx container

  • Mounts the Docker volume my_volume into the container

  • Uses the mounted volume as Nginx’s document root


Verify the Container

docker ps

Inspect Container Mounts

docker inspect nginx-volume-demo

Search for "Mounts" to see:

  • Volume name

  • Mount path

  • Type (volume)


8️⃣ Differences Between -v and --mount (Official Docker Behavior)

Docker supports two syntaxes for mounting storage into containers:

  • -v or --volume (older, shorter syntax)

  • --mount (newer, explicit syntax)

Both are fully supported and widely used.
However, their behavior differs in some important scenarios.


Key Behavioral Difference (From Docker Documentation)

Scenario-v / --volume--mount
Bind-mount path does not exist on hostDocker creates the directory automaticallyDocker throws an error
Syntax readabilityLowerHigher
Explicit configurationLimitedStrong
Error visibilityLowerHigher

Why This Difference Exists

The -v flag has existed since the early versions of Docker.
Because of backward compatibility, its behavior cannot be changed without breaking existing scripts.

The --mount flag was introduced later to:

  • Be more explicit

  • Fail fast on configuration mistakes

  • Improve readability for production setups


Docker’s Recommendation

Docker recommends using --mount for production deployments because it is more explicit and easier to understand.

👉 This does not mean -v is wrong or deprecated.
👉 -v is still commonly used, especially for quick testing and local development.


9️⃣ Deleting Docker Volumes Safely

Why Volume Deletion Sometimes Fails

If you try:

docker volume rm my_volume

You may see:

volume is in use

This means:
👉 A container is still using the volume


Correct Way to Delete a Volume

Step 1: Stop the Container

docker stop nginx-volume-demo

Step 2: Remove the Container

docker rm nginx-volume-demo

Step 3: Remove the Volume

docker volume rm my_volume

Remove All Unused Volumes

docker volume prune

⚠️ Deletes only unused volumes.


Conclusion

Docker containers are designed to be temporary and disposable, which makes them lightweight, reproducible, and easy to replace. However, real-world applications require data to persist beyond the lifecycle of a single container. This fundamental mismatch is what Docker Volumes and Bind Mounts are designed to address.

In this blog, we explored:

  • Why containers lose data by default

  • How Docker Volumes solve the problem of persistent storage

  • How Bind Mounts provide direct access to host filesystems

  • The practical differences between Volumes and Bind Mounts

  • The lifecycle of Docker Volumes and why they outlive containers

  • How to mount storage into containers using both -v and --mount

  • Why Docker recommends --mount for clearer and safer configurations

The key takeaways are:

  • Containers are temporary runtimes

  • Volumes are persistent storage managed by Docker

  • Bind mounts directly expose host paths to containers

Understanding these concepts moves you beyond just executing Docker commands. It helps you reason about data safety, portability, and production readiness—which are critical when building real-world containerized applications.

Once this foundation is clear, working with databases, stateful services, Docker Compose, and orchestration tools becomes significantly easier and more predictable.

More from this blog

codeops-labs.hashnode.dev

16 posts