Docs
/
Docker Kubernetes
Chapter 5

05 — Volumes & Storage

The Problem

Containers are ephemeral — when removed, all data inside is lost.

docker run --name db postgres:16
# Insert data...
docker rm db
# Data is GONE! 💀

Storage Types

TypeManaged byPersistenceUse Case
Named VolumeDockerSurvives container removalDatabase data, app state
Bind MountHost filesystemHost directoryDevelopment (hot reload), config files
tmpfsMemory (RAM)Lost on container stopTemporary/sensitive data
Named Volume:
  Container → /var/lib/docker/volumes/my-vol/_data (Docker manages)

Bind Mount:
  Container → /home/user/project (exact host path)

tmpfs:
  Container → RAM (never written to disk)

Named Volumes

# Create volume
docker volume create pgdata

# Use volume
docker run -d --name db \
  -v pgdata:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

# Data persists even after container removal
docker rm -f db
docker run -d --name db2 \
  -v pgdata:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16
# db2 has all the data from db ✅

# Volume commands
docker volume ls
docker volume inspect pgdata
docker volume rm pgdata
docker volume prune            # Remove unused volumes

Bind Mounts

Mount a host directory into the container. Changes sync both ways.

# Development: mount source code for hot reload
docker run -d -p 3000:3000 \
  -v $(pwd)/src:/app/src \
  -v $(pwd)/package.json:/app/package.json \
  my-app-dev

# Configuration files
docker run -d \
  -v /host/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
  nginx

# :ro = read-only (container can't modify host file)

Development Workflow

# Mount source code + use node_modules from image (not host)
docker run -d -p 3000:3000 \
  -v $(pwd):/app \
  -v /app/node_modules \          # Anonymous volume — preserves container's node_modules
  my-app-dev

tmpfs (In-Memory)

# Sensitive data that shouldn't be written to disk
docker run -d \
  --tmpfs /tmp:rw,size=100m \
  --tmpfs /run/secrets:rw,size=1m \
  my-app

Volume Backup & Restore

# Backup volume to tar file
docker run --rm \
  -v pgdata:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/pgdata-backup.tar.gz -C /data .

# Restore from tar
docker run --rm \
  -v pgdata:/data \
  -v $(pwd):/backup \
  alpine sh -c "cd /data && tar xzf /backup/pgdata-backup.tar.gz"

Comparison

Named VolumeBind Mounttmpfs
Created bydocker volume create or -v name:/path-v /host/path:/path--tmpfs /path
LocationDocker-managedAny host pathRAM
PortableYes (across hosts via backup)No (tied to host path)No
PerformanceGoodSame as host FSFastest (RAM)
Use caseProduction data (DB, uploads)Development, configTemp files, secrets

Key Takeaways

  • Use named volumes for persistent data (databases, uploads) — survives container lifecycle
  • Use bind mounts for development (live reload of source code)
  • Use tmpfs for sensitive temporary data (never touches disk)
  • Mount with :ro for read-only access when container shouldn't modify data
  • Always backup volumes before destructive operations
  • Use anonymous volumes (-v /app/node_modules) to prevent host mounts from overwriting container directories