Volumes
How to persist data beyond the container lifecycle using volumes and mounts
Overview
By default, any data written inside a container disappears when the container is removed. Volumes solve this by storing data outside the container's writable layer, managed by Docker. They are the preferred way to persist databases, uploads, and any state you want to survive restarts and rebuilds.
Syntax / Usage
You can use named volumes (managed by Docker) or bind mounts (a specific path on your host). Named volumes are created automatically or explicitly and attached with -v or --mount.
# Create a named volume
docker volume create appdata
# Mount a named volume into a container
docker run -d --name db -v appdata:/var/lib/postgresql/data postgres
# Bind mount a host directory (great for local development)
docker run -d -v "$(pwd)/src:/app/src" node:20
# List and inspect volumes
docker volume ls
docker volume inspect appdata
Examples
Persist a Postgres database so data survives container recreation:
docker run -d --name pg \
-e POSTGRES_PASSWORD=secret \
-v pgdata:/var/lib/postgresql/data \
postgres:16
Mount local code into a container for live editing during development:
docker run --rm -v "$(pwd):/app" -w /app node:20 npm test
Common Mistakes
- Assuming container data persists after
docker rmwithout a volume - Mixing up mount order — it is always
source:destination - Using bind mounts in production where a named volume is more portable
- Bind mounting over a directory the image needs, hiding its original contents
- Forgetting to remove unused volumes, which silently consume disk space
See Also
docker-images-and-containers docker-compose docker-networking