Docker Volume
A Docker-managed persistent storage location on the host filesystem that exists outside the container's union filesystem. Volumes persist beyond container lifetime, can be shared between containers, and are the recommended way to store data that must survive container restarts.
Docker Volume — Persistent Storage That Outlives Containers
What Is a Docker Volume in Simple Terms?
Everything written inside a container is lost when the container is removed. A Docker volume is storage that lives outside the container — managed by Docker, stored on the host filesystem, and attached to the container at a specific path. The container can read and write to it normally, but the data persists even after the container is deleted.
Without volume: Container runs, writes data to /app/data docker rm container Data is GONE permanently With volume: Container runs, writes data to /app/data /app/data is mounted from volume postgres-data docker rm container Volume postgres-data still exists with all data New container mounts same volume Data is still thereVolume vs Bind Mount vs tmpfs
Docker Volume (recommended for production data): -v postgres-data:/var/lib/postgresql/data Stored at: /var/lib/docker/volumes/postgres-data/_data Managed by Docker Survives container removal Portable between containers Bind Mount (for development): -v /host/path:/container/path Uses actual host filesystem path Changes on host appear in container immediately Good for: code hot-reload, config injection tmpfs (for temporary sensitive data): --tmpfs /tmp In-memory only — fastest I/O Lost when container stops Good for: secrets, caches that should not persistWorking With Volumes
# Create a named volumedocker volume create postgres-data # Use in docker rundocker run -d \ --name postgres \ -v postgres-data:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=secret \ postgres:15 # List volumesdocker volume ls# DRIVER VOLUME NAME# local postgres-data # Inspect — find where data is stored on hostdocker volume inspect postgres-data# "Mountpoint": "/var/lib/docker/volumes/postgres-data/_data" # Remove a volume (permanent data deletion)docker volume rm postgres-data# Error if a container is using it # Remove all unused volumesdocker volume prune# WARNING: deletes volumes not used by any container # In Docker Composeservices: postgres: volumes: * postgres-data:/var/lib/postgresql/data volumes: postgres-data: # top-level declaration — Docker manages itBacking Up and Restoring Volumes
# Backup to tar filedocker run --rm \ -v postgres-data:/source:ro \ -v $(pwd):/backup \ alpine \ tar czf /backup/postgres-backup.tar.gz -C /source . # Restore from tar filedocker volume create postgres-data-restoreddocker run --rm \ -v postgres-data-restored:/target \ -v $(pwd):/backup:ro \ alpine \ tar xzf /backup/postgres-backup.tar.gz -C /targetTipNamed volumes are the right choice for any data that must persist. Anonymous volumes (created without a name:
-v /var/lib/postgresql/data) also persist but are hard to manage — they get random IDs and are difficult to back up or migrate. Always name your volumes.
Common MistakeStoring database data in the container's own filesystem instead of a volume. The container filesystem uses OverlayFS which is slower for database I/O and is deleted with the container. Always use
-v named-volume:/db/data/pathfor any database container.
Frequently Asked Questions
Why use a named volume instead of just bind-mounting a host directory for persistent data?
A bind mount ties your container to a specific, hardcoded path on that host's filesystem, with permissions and existence entirely your responsibility. A named volume is managed entirely by Docker — created, tracked, and cleaned up through the Docker API — so it's portable across environments (the same `docker-compose.yml` works on any host without a path that must already exist), and Docker handles the mount lifecycle rather than you managing raw host paths, which matters when moving from local dev to a server with a different filesystem layout.
What's the common misconception about volume durability that leads to data loss?
Volumes persist across container restarts and even container removal (`docker rm`), but they are not automatically backed up, replicated, or protected from `docker volume rm` or `docker system prune --volumes`. Teams sometimes assume 'it's a volume, so it's safe' and skip a real backup strategy for stateful data like a Postgres volume, only to lose it during a careless prune or a host failure — a volume solves persistence-through-restart, not disaster recovery.