Docker Volumes Explained
Understand Docker volumes, persistent container storage, volume commands, Docker Compose configuration and best practices for managing application data.
Docker containers are designed to be disposable, but the data created by applications often needs to survive beyond the lifetime of a container. Databases, uploaded files, generated reports, caches and other persistent application data cannot always be stored safely inside the container's writable layer.
Docker volumes provide a dedicated mechanism for storing persistent data outside the container's writable filesystem. Volumes can be attached to containers, reused by multiple containers and managed independently from the containers that use them.
What Is a Docker Volume?
A Docker volume is a storage location managed by Docker that can be mounted into one or more containers. The volume exists independently from the container, which means its data can remain available even after the container is removed.
Instead of storing important application data directly inside a container, an application can write that data to a directory backed by a Docker volume. Docker manages the volume's lifecycle and storage location while the application sees it as a normal directory inside the container.
docker volume create app-data
docker run -d --name app -v app-data:/var/lib/app my-appWhy Use Volumes?
The main reason to use a Docker volume is persistence. Containers can be stopped, recreated or replaced without necessarily losing the data stored in an attached volume.
- Persist data beyond a container's lifetime.
- Separate application data from container images.
- Reuse storage across containers.
- Store database files outside the container layer.
- Make container replacement safer.
- Allow Docker to manage storage lifecycle.
Container Storage Without a Volume
Every Docker container has a writable layer where changes made during its lifetime are stored. This layer is tied to the container itself. If the container is removed, data stored only in that layer is removed with it.
Container
├── Image layers
└── Writable container layer
└── Application dataContainer Storage With a Volume
When a volume is mounted into a container, the application writes to the mounted directory while Docker stores the underlying data separately from the container's writable layer.
Docker Host
└── Docker Volume
└── Persistent application data
↑
│ mounted into
│
Container
└── /var/lib/appCreating a Volume
Volumes can be created explicitly with docker volume create. Creating a volume before starting a container makes the storage resource visible and independently manageable.
docker volume create app-dataDocker assigns the requested name to the volume and creates the storage managed by the Docker engine. The volume can then be mounted into containers.
Listing Volumes
The docker volume ls command displays volumes known to the Docker engine.
docker volume ls| Command | Purpose |
|---|---|
| docker volume create | Create a volume |
| docker volume ls | List volumes |
| docker volume inspect | View volume details |
| docker volume rm | Remove a volume |
| docker volume prune | Remove unused volumes |
Inspecting a Volume
The docker volume inspect command displays information about a volume, including its name, driver and storage location managed by Docker.
docker volume inspect app-dataMounting a Volume Into a Container
A volume is mounted by specifying the volume name and the target directory inside the container. The target directory becomes the location where the application accesses persistent data.
docker run -d --name database -v postgres-data:/var/lib/postgresql/data postgresIn this example, postgres-data is the Docker volume and /var/lib/postgresql/data is the directory inside the PostgreSQL container where the database stores its files.
The --mount Syntax
Docker also provides the --mount option for defining mounts explicitly. Compared with the shorter -v syntax, --mount uses named options that can make complex configurations easier to read.
docker run -d --name database --mount source=postgres-data,target=/var/lib/postgresql/data postgres| Syntax | Characteristics |
|---|---|
| -v | Short and commonly used |
| --mount | More explicit and descriptive |
Volumes vs Bind Mounts
Docker supports several ways to mount data into containers. The two most common are volumes and bind mounts. Both make host-side data available inside a container, but Docker manages them differently.
| Feature | Volume | Bind Mount |
|---|---|---|
| Managed by Docker | Yes | No |
| Storage location | Docker-managed | Explicit host path |
| Portable configuration | Usually easier | Depends on host paths |
| Development source code | Less common | Very common |
| Persistent application data | Common | Possible |
Volumes are generally a good choice when an application needs persistent data managed by Docker. Bind mounts are often more convenient when a developer needs direct access to specific files or directories on the host system.
Anonymous Volumes
A container can also use an anonymous volume without explicitly assigning a reusable volume name. Docker generates an identifier for the volume automatically.
docker run -d --name app -v /var/lib/app my-appNamed Volumes
Named volumes have an explicit name and can be referenced by multiple containers or future container instances. They are especially useful for databases and other stateful services.
docker volume create database-data
docker run -d --name database -v database-data:/var/lib/database my-databaseSharing a Volume Between Containers
A volume can be mounted into multiple containers. This can be useful when several services need access to the same persistent files, although applications must be designed to handle concurrent access safely.
docker run -d --name writer -v shared-data:/data writer-image
docker run -d --name reader -v shared-data:/data reader-imageRead-Only Volume Mounts
A volume can be mounted as read-only when a container needs to consume data without modifying it. This is useful for reducing accidental writes and enforcing a clearer separation between readers and writers.
docker run -d --name web -v shared-data:/data:ro nginxDocker Volumes With Docker Compose
Docker Compose provides a convenient way to define named volumes alongside services. Declaring volumes at the top level allows Compose to create and manage them as part of the application configuration.
services:
database:
image: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:With this configuration, Docker Compose creates the postgres-data volume when necessary and mounts it into the database service. The volume remains separate from the PostgreSQL container itself.
Volume Lifecycle in Compose
Compose manages services and their declared volumes separately. Recreating a service does not normally mean that its named volume data is automatically deleted. This makes volumes particularly useful for development databases and other stateful services.
docker compose up -d
docker compose down
docker compose up -dRemoving Volumes
Volumes can be removed explicitly with docker volume rm. Docker will refuse to remove a volume that is still in use by a container.
docker volume rm app-dataRemoving Unused Volumes
Docker can accumulate unused volumes over time, especially when containers are frequently created and removed during development. The docker volume prune command can remove volumes that are no longer being used.
docker volume pruneVolumes for Databases
Databases are one of the most common use cases for Docker volumes. Database containers can be replaced during upgrades, configuration changes or development workflows while their data remains in a separate volume.
services:
db:
image: postgres
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:The exact mount path depends on the database image. Always check the image documentation before selecting a directory for persistent database storage.
Volumes for Uploaded Files
Applications that allow users to upload images, documents or other files can also use volumes to keep those files separate from the application container. This allows the application container to be rebuilt without deleting uploaded content.
services:
app:
image: my-app
volumes:
- uploads:/app/uploads
volumes:
uploads:Volumes and Container Updates
Container images are commonly replaced when applications are updated. Persistent volumes allow application state to remain available while the container image changes, which is one of the main advantages of separating application code from persistent data.
Old container
│
├── Application code
│
└── persistent volume
│
▼
New container
└── same volumeVolume Drivers
Docker volumes use storage drivers to determine how the data is provided. The default local driver stores data on the Docker host, while other drivers can integrate Docker with external or specialized storage systems.
docker volume create --driver local app-dataExternal volume drivers can be useful in environments where storage must be provided by network storage systems or other infrastructure. The available drivers depend on the Docker environment and installed plugins.
Backing Up a Volume
A Docker volume is not automatically a backup. Persistent storage protects data from container removal, but it does not protect against accidental deletion, corruption or infrastructure failure. Important volumes should therefore be included in a backup strategy.
docker run --rm -v app-data:/source -v "$PWD:/backup" alpine tar czf /backup/app-data.tar.gz -C /source .This pattern starts a temporary container, mounts the volume as /source and mounts a host directory as /backup. The tar command then creates an archive containing the volume's files.
Restoring a Volume Backup
A backup archive can be extracted into a newly created volume. The exact procedure depends on the application and whether the service must be stopped during restoration.
docker volume create restored-data
docker run --rm -v restored-data:/target -v "$PWD:/backup" alpine tar xzf /backup/app-data.tar.gz -C /targetCommon Mistakes
- Storing important data only inside the container writable layer.
- Deleting volumes without checking their contents.
- Assuming volumes are automatically backed up.
- Using anonymous volumes when a named volume is easier to manage.
- Sharing a volume between applications without considering concurrent access.
- Using the wrong mount path for a database image.
- Running volume cleanup commands without reviewing the affected resources.
Best Practices
- Use named volumes for important persistent application data.
- Keep application code and persistent state separate.
- Use read-only mounts when a container only needs to read data.
- Define application volumes in Docker Compose when using Compose-based deployments.
- Back up important volumes regularly.
- Test restoration procedures before relying on backups.
- Document which services own and use each volume.
- Remove unused volumes carefully to avoid accidental data loss.
Docker Volumes vs Container Lifecycle
The key idea behind Docker volumes is that application state can have a different lifecycle from the container that uses it. Containers may be recreated frequently, while persistent data may need to survive for months or years.
| Resource | Typical Lifecycle |
|---|---|
| Container | Short-lived and replaceable |
| Image | Versioned application package |
| Volume | Persistent application data |
When Should You Use a Volume?
Volumes are a strong choice when data needs to survive container replacement and Docker should manage the storage. They are particularly useful for databases, uploaded files, application state and development services that need persistent data.
| Use Case | Volume Suitability |
|---|---|
| Database data | Excellent |
| User uploads | Excellent |
| Persistent application state | Excellent |
| Development database | Excellent |
| Source code editing | Usually bind mount |
| Temporary cache | Depends on requirements |
Frequently Asked Questions
What is a Docker volume?
A Docker volume is storage managed by Docker that can be mounted into containers and used to keep data separate from the container's writable filesystem.
Do Docker volumes survive container deletion?
Yes. A named volume normally remains after its container is removed unless the volume itself is explicitly deleted.
What is the difference between a volume and a bind mount?
Docker manages volumes, while bind mounts map an explicitly selected path from the host filesystem into a container.
Are Docker volumes automatically backed up?
No. Volumes provide persistent storage but are not a substitute for backups. Important volume data should be included in a separate backup and recovery strategy.
Can multiple containers use the same Docker volume?
Yes. Multiple containers can mount the same volume, although applications must handle concurrent access correctly.
Should databases use Docker volumes?
Volumes are commonly used for database persistence because they allow the database container to be recreated while keeping the database files separate from the container lifecycle.
Helpful Docker Tools
A Docker Compose Generator helps create Compose configurations with services and volume definitions, a Docker Compose Formatter formats and organizes YAML configuration, an Environment Variable Generator helps create environment configuration for containerized applications, a dotenv Parser helps inspect environment files, and a Dockerfile Generator assists with creating Docker images that can be used together with persistent volumes.
Conclusion
Docker volumes provide a reliable way to separate persistent application data from disposable containers. They are especially valuable for databases, uploaded files and other state that must survive container replacement. By using named volumes, choosing appropriate mount modes, defining volumes clearly in Docker Compose and maintaining a tested backup strategy, developers can build Docker applications that are easier to update, maintain and recover.