Docker Volumes – Persisting Data Beyond the Container
Containers are designed to be temporary. When you delete a container, everything inside its writable layer disappears — including your database records, uploaded files, and log data. Docker volumes solve this problem by storing data outside the container so it survives container restarts and deletions.
The Problem Without Volumes
Imagine you run a MySQL database inside a container. You add 1000 records over two weeks. Then you run docker rm to remove the container for an upgrade. All 1000 records are gone forever — because they lived inside the container's writable layer.
Without volumes:
Container (mysql) ──┐
/var/lib/mysql/ │ ← your database files live here
- ibdata1 │ ← INSIDE the container
- *.ibd files │
│
docker rm mysql ────┘ ← container deleted → data deleted
How Volumes Work
A Docker volume is a special directory managed by Docker, stored on your host machine at a known location. Docker mounts this directory into the container at a path you specify. The container reads and writes data there as if it were a normal folder — but the actual data lives on your host, not inside the container.
With volumes:
Your Host Machine Container (mysql)
┌─────────────────┐ ┌──────────────────┐
│ Docker managed │ │ │
│ volume storage │ │ /var/lib/mysql │
│ /var/lib/docker │◄──mount────│ (data appears │
│ /volumes/ │ │ here) │
│ mydb-data/ │ │ │
└─────────────────┘ └──────────────────┘
↑
Data lives here, outside the container.
Delete the container → data still safe.
Three Types of Docker Storage
Type 1: Named Volumes (recommended for most cases) docker run -v mydata:/var/lib/mysql mysql ↑ Docker creates and manages the volume Type 2: Bind Mounts (good for development) docker run -v /home/user/data:/var/lib/mysql mysql ↑ You specify the exact host directory path Type 3: tmpfs Mounts (temporary in-memory storage) docker run --tmpfs /tmp nginx ↑ Stored in host RAM, disappears on container stop
Working with Named Volumes
Create a named volume:
docker volume create mydb-data
Run a MySQL container with the volume:
docker run -d \ --name mysql-server \ -e MYSQL_ROOT_PASSWORD=secret \ -v mydb-data:/var/lib/mysql \ mysql:8.0
Stop and remove the container, then recreate it with the same volume:
docker stop mysql-server docker rm mysql-server docker run -d \ --name mysql-server \ -e MYSQL_ROOT_PASSWORD=secret \ -v mydb-data:/var/lib/mysql \ mysql:8.0
Your database records are still there. The volume survived the container deletion.
Volume Commands
List all volumes: docker volume ls Inspect a volume (see its location on host): docker volume inspect mydb-data Remove a specific volume: docker volume rm mydb-data Remove all unused volumes: docker volume prune
Bind Mounts — Perfect for Development
Bind mounts link a specific folder on your host machine to a folder inside the container. Changes you make to files on your host instantly appear inside the container. This is ideal for development — you edit code in your editor and the running container sees the changes immediately.
docker run -d \ --name dev-app \ -p 5000:5000 \ -v $(pwd)/src:/app/src \ my-python-app:dev You edit src/app.py on your laptop → Container sees the change instantly → No rebuild needed during development
Bind Mount Diagram:
Your Laptop Container
/home/you/project/src/ ←──────── /app/src/
↕ (real-time sync)
You edit files here
Editor shows them
Read-Only Volumes
Mount a volume as read-only to prevent the container from modifying files:
docker run -v myconfig:/config:ro nginx
↑
ro = read-only
Use this for configuration files, SSL certificates, or secrets that containers should read but never modify.
When to Use Which Storage Type
┌──────────────────┬────────────────────────────────────────┐ │ Named Volumes │ Databases, persistent app data │ │ │ Data that must survive container life │ ├──────────────────┼────────────────────────────────────────┤ │ Bind Mounts │ Development: live code editing │ │ │ Sharing config files from host │ ├──────────────────┼────────────────────────────────────────┤ │ tmpfs Mounts │ Sensitive data (passwords in memory) │ │ │ Temporary scratch space │ └──────────────────┴────────────────────────────────────────┘
