This content originally appeared on DEV Community and was authored by Darshan Vasani
Docker Volumes β A2Z Storage Guide
What is a Docker Volume?
A Docker volume is a persistent storage mechanism managed by Docker outside the container filesystem.
Volumes survive container restarts
Volumes are managed by Docker
Theyβre perfect for storing databases, logs, user uploads, and config files
Real-World Analogy:
Think of a volume as a USB stick plugged into your container.
- You can eject the container
- The USB (volume) still has all your files
Why Use Volumes?
![]() |
![]() |
---|---|
Persistent Storage | Data stays even after container dies |
Decoupled | Separate from container logic |
Shared Access | Mount same volume into multiple containers |
Backup Friendly | Easy to archive/export |
Safe from image rebuilds | Won’t be deleted accidentally |
Types of Docker Volume Mounts
Type | Syntax Example | Use Case |
---|---|---|
![]() |
-v my-volume:/app/data |
Default, managed by Docker |
![]() |
-v /host/folder:/container/folder |
Use host machine’s file system |
![]() |
-v /app/data |
Randomly named, temporary |
1. Using a Named Volume
docker volume create mydata
docker run -d \
--name db \
-v mydata:/var/lib/mysql \
mysql
The data is stored in:
/var/lib/docker/volumes/mydata/_data
2. Attaching Host Folders (Bind Mounts)
docker run -d \
--name webapp \
-v /home/user/project:/usr/src/app \
node:alpine
Mounts a host folder directly inside the container.
Bind mounts are powerful but risk exposing sensitive host files if misused.
Differences: Volume vs Bind Mount
Feature | Volume (Docker-managed) | Bind Mount (Host folder) |
---|---|---|
Managed by Docker | ![]() |
![]() |
Host portability | ![]() |
![]() |
Data safety | ![]() |
![]() |
Security | ![]() |
![]() |
3. Share Volume Between Multiple Containers
Example:
docker volume create shared-data
docker run -d --name writer \
-v shared-data:/data \
busybox sh -c "echo hello > /data/file.txt && sleep 9999"
docker run --rm --name reader \
-v shared-data:/data \
busybox cat /data/file.txt
Both
writer
and reader
share the same volume.
Read-only Volume Mount
Prevent writing:
-v mydata:/app/data:ro
Makes volume read-only inside the container!
Volume Lifecycle Commands
![]() |
![]() |
---|---|
docker volume create <name> |
Create a volume |
docker volume ls |
List all volumes |
docker volume inspect <name> |
View volume details |
docker volume rm <name> |
Delete volume |
docker volume prune |
Delete all unused volumes |
Using Volumes in docker-compose.yml
version: "3.9"
services:
db:
image: postgres
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Docker creates & manages the
pgdata
volume
Volume Naming Tip
- Named volumes persist and can be reused by name
- Anonymous volumes are created automatically and can be hard to track
docker run -v /data nginx # Anonymous volume
docker run -v myvol:/data nginx # Named volume ✅
Backing Up & Restoring Volumes
Backup:
docker run --rm \
-v myvolume:/data \
-v $(pwd):/backup \
busybox tar czvf /backup/backup.tar.gz /data
Restore:
docker run --rm \
-v myvolume:/data \
-v $(pwd):/backup \
busybox tar xzvf /backup/backup.tar.gz -C /
Volume Gotchas to Avoid
![]() |
![]() |
---|---|
Not naming volumes | Hard to manage & reuse |
Mixing bind mount with sensitive paths | Potential host damage |
Forgetting to prune | Unused volumes pile up |
Overwriting app folder with empty volume | App might not start! |
Summary Table
Type | Managed | Persistent | Use Case |
---|---|---|---|
![]() |
Docker | ![]() |
Safe default, backups |
![]() |
Host | ![]() |
Mount local code |
![]() |
Docker | ![]() |
Quick test, not tracked |
Final Takeaways
Volumes are best practice for persistent, portable storage.
Use named volumes for databases, uploads, logs.
Use bind mounts for local dev.
Share volumes to enable inter-container communication via files.
Clean up with
docker volume prune
.
This content originally appeared on DEV Community and was authored by Darshan Vasani