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
| Type | Managed by | Persistence | Use Case |
|---|---|---|---|
| Named Volume | Docker | Survives container removal | Database data, app state |
| Bind Mount | Host filesystem | Host directory | Development (hot reload), config files |
| tmpfs | Memory (RAM) | Lost on container stop | Temporary/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 Volume | Bind Mount | tmpfs | |
|---|---|---|---|
| Created by | docker volume create or -v name:/path | -v /host/path:/path | --tmpfs /path |
| Location | Docker-managed | Any host path | RAM |
| Portable | Yes (across hosts via backup) | No (tied to host path) | No |
| Performance | Good | Same as host FS | Fastest (RAM) |
| Use case | Production data (DB, uploads) | Development, config | Temp 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
:rofor 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