The Problem: Containers Are Ephemeral

Before talking about volumes, you need to understand a fundamental concept: Docker containers are ephemeral. What does this mean?

Imagine you have a container running a database. You insert data, everything works perfectly. Then you stop the container, restart it, and… the data is gone. Poof, vanished.

This happens because each container has its own isolated filesystem that lives and dies with the container itself. It’s like writing on sand: as soon as the wave comes, everything disappears.

What Is a Docker Volume?

A Docker volume is a mechanism for storing data outside the container, so that it persists even when the container is stopped, restarted, or deleted.

Think of volumes as an external hard drive that you connect to your container. Data is written to this “external drive” and remains safe regardless of what happens to the container.

Why Use Volumes?

  • Persistence: data survives the container lifecycle
  • Sharing: multiple containers can access the same data
  • Backup: it’s easier to back up data
  • Performance: volumes are optimized for I/O operations
  • Portability: you can move data between different hosts

Three Ways to Manage Data in Docker

Docker offers three approaches for data management. Let’s look at them from most recommended to least.

Volumes are fully managed by Docker and stored in a special directory on the host (/var/lib/docker/volumes/ on Linux).

1
2
3
4
5
# Create a volume
docker volume create my-volume

# Use the volume in a container
docker run -v my-volume:/app/data my-image

Advantages:

  • Managed by Docker (easy to create, delete, inspect)
  • Work on Linux, Windows, and Mac
  • Can be shared between multiple containers
  • Support drivers for remote storage (cloud, NFS, etc.)

2. Bind Mounts - Direct Connection

Bind mounts connect a specific folder on your computer directly to the container.

1
2
# Connect a local folder to the container
docker run -v /path/on/your/pc:/app/data my-image

When to use them:

  • During development, to see code changes in real time
  • When you need access to specific files on the host system
  • To share configurations between host and container

Warning: bind mounts depend on the host filesystem structure, so they’re less portable.

3. tmpfs Mounts - Temporary Data in Memory

tmpfs mounts store data in the host’s RAM, not on disk.

1
docker run --tmpfs /app/temp my-image

When to use them:

  • For sensitive data that shouldn’t be written to disk
  • For high-performance temporary caches
  • Data is lost when the container stops (and that’s exactly what you want)

Essential Volume Commands

Create a Volume

1
docker volume create volume-name

List Volumes

1
docker volume ls

Inspect a Volume

1
docker volume inspect volume-name

This command shows where the volume is physically stored and other useful information.

Delete a Volume

1
2
3
4
5
# Delete a specific volume
docker volume rm volume-name

# Delete all unused volumes
docker volume prune

Warning: deleting a volume means losing all the data it contains. There’s no recycle bin or recovery.

Practical Examples

Example 1: MySQL Database with Persistent Data

Without a volume, every time you restart the MySQL container you lose all data. Here’s how to fix it:

1
2
3
4
5
6
7
8
9
# Create a volume for MySQL data
docker volume create mysql-data

# Start MySQL using the volume
docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=password123 \
  -v mysql-data:/var/lib/mysql \
  mysql:8

Now you can stop, restart, or even delete and recreate the container: the database data will remain intact in the mysql-data volume.

Example 2: Web Development with Bind Mount

During development, you want code changes to be immediately visible in the container:

1
2
3
4
5
docker run -d \
  --name my-site \
  -p 8080:80 \
  -v $(pwd)/src:/var/www/html \
  php:apache

Any changes to files in the src folder will be immediately available in the container.

Example 3: Sharing Data Between Containers

Two containers that need to access the same files:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Create the shared volume
docker volume create shared-data

# Container that writes
docker run -d --name writer -v shared-data:/data alpine \
  sh -c "while true; do date >> /data/log.txt; sleep 5; done"

# Container that reads
docker run -it --name reader -v shared-data:/data alpine \
  tail -f /data/log.txt

Volumes in Docker Compose

When using Docker Compose, defining volumes is even simpler:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
version: '3.8'

services:
  database:
    image: postgres:15
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

  app:
    image: my-app
    volumes:
      - ./code:/app              # Bind mount for development
      - logs:/app/logs           # Volume for logs

volumes:
  postgres-data:    # Docker-managed volume
  logs:             # Docker-managed volume

With a simple docker-compose up, Docker automatically creates the necessary volumes.

Backing Up and Restoring Volumes

Back Up a Volume

1
2
3
4
docker run --rm \
  -v volume-name:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz -C /source .

This command:

  1. Mounts the volume in read-only mode (ro)
  2. Creates a compressed archive in the current directory

Restore a Backup

1
2
3
4
docker run --rm \
  -v volume-name:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/backup.tar.gz -C /target

Common Mistakes to Avoid

1. Forgetting to Use Volumes for Databases

If you use a database in Docker without a volume, you will lose all data. Always.

2. Using Bind Mounts in Production

Bind mounts are great for development, but in production use Docker volumes for better portability and security.

3. Not Backing Up Volumes

Volumes are not automatically included in system backups. Plan regular backups.

4. Accumulating Orphan Volumes

When you delete containers, volumes remain. Periodically use:

1
docker volume prune

To delete volumes no longer connected to any container.

When to Use What: Summary

ScenarioSolution
Production databaseDocker Volume
Local developmentBind mount
Temporary sensitive datatmpfs
Sharing between containersDocker Volume
Configuration filesBind mount or Volume
Application logsDocker Volume

Conclusions

Docker volumes solve one of the fundamental problems of containers: data persistence. Without volumes, containers would only be useful for stateless applications.

Remember the golden rules:

  • Always use volumes for databases
  • Use bind mounts for local development
  • Regularly back up important volumes
  • Periodically clean up orphan volumes

Once you understand the concept, volumes become as natural as saving a file to disk. And your data will finally be safe, regardless of what happens to the containers.


In the next article, we’ll look at how to manage networks in Docker to make containers communicate with each other.