Chapter 09 • Storage & Networking

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 TypeHost LocationPerformance & IsolationIdeal Production Use Case
Named VolumeManaged by Docker (/var/lib/docker/volumes/)Highest I/O performance. Completely decoupled from host OS directory structures.Stateful Databases (PostgreSQL, MySQL, MongoDB, Redis).
Bind MountAny 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 MountHost 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:v1

4. 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-data

5. Solving UID / GID Permission Conflicts

The Common "EACCES: permission denied" Bug: When you bind-mount a host folder into a container running as a non-root user (e.g. 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 →

Explore Related Tools

Hand-picked utilities and calculators related to this tool.

Related Tools