Managing Persistent Data in Docker with Volumes

Containers get a temporary writable layer by default, which disappears the moment a container is deleted — fine for scratch data, but risky for anything worth keeping. This article explains how Docker volumes decouple persistent data from container lifecycles, and walks through creating, using, and sharing them safely.

Docker VolumesPersistent DataStateful Applications

~4 min read · Updated Sep 5, 2026

Introduction

Applications generally fall into two categories: stateful apps, which create and manage data worth keeping, and stateless apps, which don't. Docker has a solution for each — ephemeral local storage for temporary data, and volumes for anything that needs to persist beyond a container's lifetime.

Containers Without Volumes

Every container is built from stacked, read-only image layers topped with a thin, writable layer of local storage. Any file changes made inside a running container are written to this layer, which Docker merges into the container's overall view of the filesystem. However, this storage is tightly coupled to the container's lifecycle — it's created with the container and destroyed along with it, on Linux typically stored under /var/lib/docker//.

Because of this, containers should be treated as immutable: rather than modifying a live container's configuration, the correct approach is to build and test a new container with the required changes and replace the old one. This local storage layer is perfectly suited to temporary, non-persistent data, but not to anything that needs to survive beyond the container itself.

Containers With Volumes

Volumes solve this by existing as independent objects with their own lifecycle, completely decoupled from any single container. This offers three key benefits: volumes survive container deletion, they can be mapped to specialized external storage systems, and multiple containers — even across different hosts — can share the same volume.

Creating and Managing Volumes

Volumes are first-class Docker objects, managed through the docker volume subcommand:

docker volume create myvol

By default, Docker uses the local driver, meaning the volume is only accessible to containers on the same host. Third-party drivers extend this to support cloud storage or on-premises systems like SAN and NAS. Existing volumes can be listed and inspected with:

docker volume ls
docker volume inspect myvol

The inspect output reveals the volume's actual location on the host filesystem, though directly accessing it that way is not recommended practice. Unused volumes can be removed individually or in bulk:

docker volume rm myvol
docker volume prune --all

Neither command will delete a volume that's currently mounted into a container.

Using Volumes with Containers

A volume can be mounted into a container with the --mount flag. If the named volume doesn't already exist, Docker creates it automatically:

docker run -it --name voltainer --mount source=bizvol,target=/vol alpine

Data written to the mounted path persists in the volume even after the container is deleted. This makes it possible to remove the original container entirely and mount the same volume, with all its data intact, into a brand-new one:

docker run -it --name newctr --mount source=bizvol,target=/vol alpine sh

Volumes can also be declared inside a Dockerfile using the VOLUME instruction, though the actual host directory mapping can only be specified at deployment time, not in the Dockerfile itself.

Sharing Storage Across Nodes

Integrating Docker with external storage systems — cloud storage or enterprise NAS/SAN — makes it possible to present the same shared volume to containers running on entirely different hosts. This requires a compatible volume driver and careful application design, since concurrent writes from containers on different nodes can lead to data corruption if updates to shared data aren't properly coordinated — for example, one container's cached write silently overwriting a more recent update from another.

Conclusion

Docker volumes are the recommended way to handle any data that needs to outlive a container. By existing as independent, first-class objects, they let containers stay disposable and immutable while the data that actually matters remains safe, portable, and shareable across the container lifecycle.

Written & researched by Dr. Shahin Siami

Related Articles

How Docker Uses Linux Security Technologies: Namespaces, Cgroups, and More

Docker's security model is built on layered defense, combining well-established Linux kernel technologies with sensible defaults out of the box. This article explains how namespaces, control groups, capabilities, mandatory access control, and seccomp work together to isolate and secure containers.

Continue

How Docker Overlay Networks Work: VXLAN Under the Hood

Overlay networks let containers on different hosts communicate as if they shared a single flat network, forming the backbone of most cloud-native microservices apps. This article covers how to build, encrypt, and test a Docker overlay network across a Swarm cluster, and explains the VXLAN tunneling technology powering it behind the scenes.

Continue

Connecting Docker Containers to VLANs and Load Balancing with Swarm

Beyond basic bridge networks, Docker can connect containers directly to existing physical VLANs, resolve service names automatically, and distribute traffic across a Swarm cluster. This article covers the macvlan driver, Docker's built-in service discovery, and Swarm's ingress load balancing mesh.

Continue

Understanding Docker Networking: CNM, Libnetwork, and Bridge Networks

Docker networking is built on an open design called the Container Network Model, implemented through libnetwork and extended by pluggable drivers. This article covers the theory behind Docker networking and walks through creating and testing single-host bridge networks, including name resolution and port mapping.

Continue

Deploying and Managing Multi-Node Clusters with Docker Swarm

Docker Swarm turns a group of Docker nodes into a secure, highly available cluster with built-in application orchestration. This article covers building a multi-node swarm, deploying a microservices app declaratively, and performing rolling updates without losing desired-state consistency.

Continue

Building and Running WebAssembly Apps as Docker Containers

WebAssembly (Wasm) is emerging as a lightweight alternative to traditional containers, and Docker now supports building, sharing, and running Wasm apps using familiar tools. This article walks through writing a simple Wasm app with Spin, containerizing it with Docker, and running it as a Wasm container.

Continue