By default, any data written inside a container disappears when that container is removed. Volumes solve this by storing data outside the container's writable layer, so it survives restarts, updates, and even complete container recreation.
Why This Matters
Database files, uploaded media, and configuration should never live only inside a container — running docker compose down or replacing a container for an image update would permanently destroy that data without a volume.
Named Volumes (Recommended for Most Cases)
Docker manages the storage location for you:
docker volume create app_data
docker run -d --name db -v app_data:/var/lib/mysql mysql:8.0
Listing and Inspecting Volumes
docker volume ls
docker volume inspect app_data
Bind Mounts (Mapping a Specific Host Directory)
Useful when you need direct access to the files from outside Docker (e.g. editing website files):
docker run -d --name web -v /home/deploy/site:/usr/share/nginx/html nginx
Named Volumes in Docker Compose
services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Read-Only Mounts
For files a container should never modify:
docker run -v /home/deploy/site:/usr/share/nginx/html:ro nginx
Backing Up a Named Volume
docker run --rm \
-v app_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/app_data-backup.tar.gz /data
Restoring a Named Volume
docker run --rm \
-v app_data:/data \
-v $(pwd):/backup \
alpine sh -c "cd /data && tar xzf /backup/app_data-backup.tar.gz --strip 1"
Removing Unused Volumes
docker volume prune
This only removes volumes not currently referenced by any container — review the list first if the data might still be needed.
Named Volumes vs Bind Mounts
| Feature | Named Volume | Bind Mount |
|---|---|---|
| Managed by Docker | Yes | No, you manage the path |
| Best for | Databases, application state | Website source files, config editing from host |
| Portability | High | Tied to a specific host path |
Common Errors
Data disappeared after recreating a container — the container was run without a volume; the data existed only in its writable layer and was lost on removal.
Permission denied writing to a bind mount — check the host directory's ownership matches the user the container process runs as.
Best Practices
- Always use a volume for databases and any state you can't afford to lose
- Prefer named volumes for portability; use bind mounts when you need direct host-side file access
- Include volume backups in your regular backup routine, not just database dumps
FAQ
Does docker compose down delete volumes?
No, not by default — only docker compose down -v also removes named volumes. Always double-check before adding -v.
Related Articles
- Deploy Your First Docker Container
- Run MySQL/PostgreSQL/Redis in Docker Containers
- How to Set Up Automated VPS Backups
