Skip to content

Docker_volumes

Docker volumes provide persistent storage for containers. This chapter covers managing data in Docker.

Containers are ephemeral - data is lost when they stop. Volumes persist data beyond container lifecycle.

┌─────────────────────────────────────────────────────────────────────────────┐
│ Container Data Without Volumes │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Container Running Container Stopped │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Container │ │ Container │ │
│ │ ┌──────────────┐ │ │ │ │
│ │ │ App Data │ │ ────────▶ │ (Data Lost!) │ │
│ │ │ Database │ │ │ │ │
│ │ │ Logs │ │ │ │ │
│ │ └──────────────┘ │ └──────────────────┘ │
│ └──────────────────┘ │
│ │
│ Data is tied to container lifecycle │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Container Data With Volumes │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Container Running Container Stopped │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Container │ │ Container │ │
│ │ ┌──────────────┐ │ │ │ │
│ │ │ App Data │ │◀─── Volume ───────▶│ App Data │ │
│ │ └──────┬───────┘ │ │ Persists! │ │
│ └───────┼─────────┘ └────────┬─────────┘ │
│ │ │ │
│ ┌───────▼──────────────────────────────────────────▼───────┐ │
│ │ Volume │ │
│ │ (/var/lib/docker/volumes/) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Data persists beyond container lifecycle │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Docker Volume Types │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ Named Volumes │ │ Bind Mounts │ │ tmpfs Mount │ │
│ └────────────────┘ └────────────────┘ └────────────────┐ │
│ │
│ Managed by Docker Host directory bind In-memory storage │
│ Persist across Access host files Fast but temporary │
│ container lifecycle directly │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Terminal window
# Create a volume
docker volume create my-data
# List volumes
docker volume ls
# Inspect volume
docker volume inspect my-data
# Run container with volume
docker run -d -v my-data:/var/lib/postgresql/data postgres:15
# Remove volume
docker volume rm my-data
Terminal window
# View volume details
docker volume inspect my-data
# Output:
# [
# {
# "CreatedAt": "2024-01-01T10:00:00Z",
# "Driver": "local",
# "Labels": {},
# "Mountpoint": "/var/lib/docker/volumes/my-data/_data",
# "Name": "my-data",
# "Options": {},
# "Scope": "local"
# }
# ]

Mount host directories into containers:

Terminal window
# Mount host directory
docker run -v /host/path:/container/path nginx
# Mount current directory
docker run -v $(pwd):/workspace myapp
# Mount with read-only
docker run -v $(pwd):/workspace:ro myapp
┌─────────────────────────────────────────────────────────────────────────────┐
│ Bind Mount Use Cases │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Development Environments │
│ - Mount source code for live reload │
│ - Changes reflect immediately │
│ │
│ 2. Configuration Files │
│ - Share host config files with containers │
│ - Easy to modify without rebuilding │
│ │
│ 3. Log Files │
│ - Access container logs from host │
│ - Centralized log management │
│ │
│ 4. Build Artifacts │
│ - Share build output between containers │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Store data in memory (temporary):

Terminal window
# tmpfs mount
docker run --tmpfs /tmp:rw,size=100m myapp
# Using mount option
docker run --mount type=tmpfs,destination=/tmp,size=100m myapp
Terminal window
# Default local driver
docker volume create my-volume
  • rexray: Cloud storage integration
  • flocker: Cross-host container storage
  • nfs: Network File System
  • ceph: Distributed storage
Terminal window
# Using a different driver (example with NFS)
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.1,rw \
--opt device=:/path/to/share \
nfs-volume
Terminal window
# Create volume
docker volume create my-volume
# List volumes
docker volume ls
# Inspect volume
docker volume inspect my-volume
# Remove volume
docker volume rm my-volume
# Remove all unused volumes
docker volume prune
# Remove unused volumes older than 24 hours
docker volume prune --filter "until=24h"
docker-compose.yml
version: '3.8'
services:
db:
image: postgres:15
volumes:
# Named volume
- db-data:/var/lib/postgresql/data
# Bind mount
volumes:
- ./config:/etc/postgresql
# tmpfs mount
tmpfs:
- /tmpfs:size=100M
app:
image: myapp
volumes:
- app-data:/app/data
- ./logs:/var/log/myapp
volumes:
db-data:
app-data:
Terminal window
# Create shared volume
docker volume create shared-data
# Container 1 writes to volume
docker run -v shared-data:/data --name writer busybox sh -c 'echo "Hello from container 1" > /data/file.txt'
# Container 2 reads from same volume
docker run -v shared-data:/data --name reader busybox cat /data/file.txt
Terminal window
# Create container with volume
docker create -v /data --name data-container busybox
# Use same volume in another container
docker run --volumes-from data-container myapp
┌─────────────────────────────────────────────────────────────────────────────┐
│ Volume Best Practices │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ✓ Use named volumes for persistent data │
│ ✓ Use bind mounts for configuration │
│ ✓ Use tmpfs for sensitive temporary data │
│ ✓ Never store application code in volumes (use bind mounts instead) │
│ ✓ Use read-only volumes when possible │
│ ✓ Backup important volumes regularly │
│ ✓ Use volume drivers for distributed storage │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Terminal window
# Backup volume to tar
docker run --rm \
-v my-volume:/data \
-v $(pwd):/backup \
busybox \
tar cvf /backup/backup.tar /data
# Restore volume from tar
docker run --rm \
-v my-volume:/data \
-v $(pwd):/backup \
busybox \
tar xvf /backup/backup.tar -C /
Terminal window
# PostgreSQL with volume
docker run -d \
--name postgres-db \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=mydb \
-v postgres-data:/var/lib/postgresql/data \
postgres:15
Terminal window
# Nginx with log volume
docker run -d \
\
-p --name nginx-web 80:80 \
-v nginx-logs:/var/log/nginx \
nginx
Terminal window
# React app with live reload
docker run -d \
--name react-dev \
-v $(pwd):/app \
-v /app/node_modules \
-p 3000:3000 \
-e CHOKIDAR_USEPOLLING=true \
node:18-alpine \
npm start

In this chapter, you learned:

  • Why volumes are needed for data persistence
  • Different volume types (named, bind, tmpfs)
  • Creating and managing volumes
  • Volume best practices
  • Backing up and sharing volumes