Docker Volumes & Data Persistence
By default, all files written inside a container reside in an ephemeral writable container layer. When the container is destroyed via docker rm, that data is permanently lost. To run stateful workloads like PostgreSQL, MongoDB, Redis, or Elasticsearch, Docker provides persistent storage abstractions that bypass the UnionFS storage driver and write directly to the host filesystem.
1. The Three Storage Paradigms: Volumes, Bind Mounts & tmpfs
Docker categorizes persistent and ephemeral mounts into three distinct architectural models:
| Mount Type | Host Location | Performance & Isolation | Ideal Production Use Case |
|---|---|---|---|
| Named Volume | Managed by Docker (/var/lib/docker/volumes/) | Highest I/O performance. Completely decoupled from host OS directory structures. | Stateful Databases (PostgreSQL, MySQL, MongoDB, Redis). |
| Bind Mount | Any user-specified host directory (e.g. $(pwd)/src) | Direct host access. Dependent on host directory tree and OS permissions. | Live Dev Hot-Reloading & injecting host configuration files. |
| tmpfs Mount | Host machine's physical RAM (never touches disk) | Fastest possible memory access. Ephemeral; purged on container stop. | Sensitive Secrets, encryption keys, or volatile caching. |
2. Modern Syntax: -v vs --mount
While the legacy -v / --volume flag is concise, modern enterprise Docker scripts prefer--mount because it is explicit, self-documenting, and produces clearer error messages:
Named Volume (PostgreSQL Database)
Mounts a named volume to the Postgres data directory:
docker run -d \ --name prod-postgres \ -e POSTGRES_PASSWORD=supersecret \ --mount type=volume,source=pg_data,target=/var/lib/postgresql/data \ -p 5432:5432 \ postgres:16-alpine
Read-Only Bind Mount (Config Files)
Prevents the container from mutating host configs:
docker run -d \ --name reverse-proxy \ --mount type=bind,source="$(pwd)/nginx.conf",target=/etc/nginx/nginx.conf,readonly \ -p 80:80 \ nginx:alpine
3. High-Security In-Memory Mounts: tmpfs
When processing payment card data, temporary private keys, or short-lived cryptographic nonces, you should never allow those bytes to touch the host SSD or hard disk. A tmpfs mount writes exclusively to kernel RAM:
docker run -d \
--name payment-token-service \
--mount type=tmpfs,target=/app/tokens,tmpfs-size=64m,tmpfs-mode=1770 \
payment-app:v14. Volume Backup & Restore Engineering
Because named volumes are managed internally by the Docker daemon, DevOps engineers use ephemeral helper containers to create deterministic compressed backups:
A. Backing Up a Named Volume to a Compressed Tarball:
# Launches a temporary Alpine container, mounts the named volume and local directory, creates a tarball, and self-destructs (--rm):
docker run --rm \
-v pg_data:/volume-data:ro \
-v $(pwd):/backup \
alpine tar czf /backup/pg_data_backup_$(date +%Y%m%d).tar.gz -C /volume-data .B. Restoring a Backup Tarball into a New Volume:
# 1. Create the new destination volume
docker volume create pg_data_restored
# 2. Extract backup tarball into the new volume
docker run --rm \
-v pg_data_restored:/volume-data \
-v $(pwd):/backup \
alpine tar xzf /backup/pg_data_backup_20261015.tar.gz -C /volume-data5. Solving UID / GID Permission Conflicts
USER node with UID 1000), file write operations will fail if the host folder is owned by root.The Fix: Align file ownership on the host machine before mounting:
# Set host directory ownership to match container user UID (e.g. 1000): sudo chown -R 1000:1000 ./uploads
Next Up: Docker Networking Deep Dive
In Chapter 10, explore bridge network drivers, embedded DNS resolution, port publishing vs exposing, and host networking.
Chapter 10: Docker Networking →