Docker Volume Mounts with -v Flag
Learn how to persist container data using Docker named volumes. Understand volume lifecycle, data sharing between containers, and why volumes are preferred over bind mounts for production data.
Detailed Explanation
Persistent Data with Docker Volumes
Container filesystems are ephemeral -- when a container is removed, all data inside it is lost. Docker volumes provide persistent storage that survives container restarts and removals.
Creating and Using Named Volumes
docker run -d --name db -v pgdata:/var/lib/postgresql/data postgres:16
This creates a named volume called pgdata (if it does not already exist) and mounts it at /var/lib/postgresql/data inside the container. PostgreSQL stores its data files in this directory, so they persist even if the container is removed and recreated.
Volume Lifecycle
Named volumes are managed independently from containers:
docker volume create mydata # Create explicitly
docker volume ls # List all volumes
docker volume inspect pgdata # Show volume details
docker volume rm pgdata # Remove a volume
docker volume prune # Remove unused volumes
Volumes persist until explicitly removed. Removing a container does not remove its associated volumes.
Sharing Volumes Between Containers
Multiple containers can mount the same volume simultaneously:
docker run -d --name writer -v shared-data:/data my-writer-app
docker run -d --name reader -v shared-data:/data my-reader-app
Both containers see the same files in /data. This enables patterns like:
- A web server and a content management system sharing a static files directory.
- A log writer and a log processor sharing a log directory.
Volume Mount Syntax
The -v flag (and the more verbose --mount) support several formats:
# Named volume
-v volume-name:/container/path
# Named volume with read-only access
-v volume-name:/container/path:ro
# Anonymous volume (auto-generated name)
-v /container/path
# Using --mount (more explicit)
--mount type=volume,source=volume-name,target=/container/path
Volumes vs. Bind Mounts
| Feature | Named Volume | Bind Mount |
|---|---|---|
| Managed by Docker | Yes | No |
| Location on host | Docker-controlled (/var/lib/docker/volumes/) |
Any host path |
| Pre-populated | Yes (copies image content) | No (overwrites with host content) |
| Backup | docker volume commands |
Standard file tools |
| Performance on macOS/Windows | Optimized | Slower (filesystem translation) |
When to Use Named Volumes
- Database storage (PostgreSQL, MySQL, MongoDB data directories)
- Application state (file uploads, generated files)
- Shared data between related containers
- CI/CD caches (node_modules, build artifacts)
Backup and Restore
Back up a volume by mounting it in a temporary container:
docker run --rm -v pgdata:/data -v $(pwd):/backup ubuntu tar czf /backup/pgdata.tar.gz -C /data .
Restore by extracting the archive into the volume:
docker run --rm -v pgdata:/data -v $(pwd):/backup ubuntu tar xzf /backup/pgdata.tar.gz -C /data
Use Case
Running a PostgreSQL database in Docker for a development project, ensuring that database data persists across container updates and host machine reboots without manual backup procedures.