Docker Volumes Guide
Volume Types Comparison
| Type | Syntax | Managed By | Use Case |
|---|---|---|---|
| Named volume | -v mydata:/app/data | Docker | Persistent app data, databases |
| Bind mount | -v /host/path:/container/path | Host OS | Dev hot-reload, config injection |
| tmpfs | --tmpfs /tmp | Memory | Sensitive temporary data |
| Anonymous volume | -v /app/data | Docker | Ephemeral data (avoid in production) |
Named Volumes
# Create volume
docker volume create pgdata
# Run container with named volume
docker run -d \
--name postgres \
-v pgdata:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret \
postgres:16
# List volumes
docker volume ls
# Inspect volume
docker volume inspect pgdata
# Copy data into volume via helper container
docker run --rm \
-v pgdata:/data \
-v $(pwd)/backup:/backup \
alpine sh -c "cp /backup/dump.tar /data/"
# Backup volume to tarball
docker run --rm \
-v pgdata:/data:ro \
-v $(pwd):/backup \
alpine tar czf /backup/pgdata-backup.tar.gz -C /data .
# Remove volume
docker volume rm pgdata
docker volume prune # remove all unused volumes
Bind Mounts
# Development: mount source code for hot-reload
docker run -d \
--name dev-server \
-v $(pwd):/app \
-w /app \
-p 3000:3000 \
node:20 npm run dev
# Read-only bind mount
docker run -d \
-v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx
# Mount with SELinux label (Linux)
docker run -v /host/data:/data:z nginx # shared label
docker run -v /host/data:/data:Z nginx # private label
# Using --mount (explicit, preferred for scripts)
docker run \
--mount type=bind,source=$(pwd)/config,target=/app/config,readonly \
myapp
tmpfs Mounts
# Mount tmpfs (in-memory, not persisted)
docker run -d \
--tmpfs /run:rw,noexec,nosuid,size=64m \
--tmpfs /tmp \
myapp
# Using --mount syntax
docker run \
--mount type=tmpfs,destination=/tmp,tmpfs-size=128m \
myapp
# Use case: store secrets/tokens in memory only
# Data is lost when container stops
Docker Compose Volumes
# docker-compose.yml
services:
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
api:
image: myapi
volumes:
- ./src:/app/src # bind mount (dev)
- /app/node_modules # anonymous (keep container's modules)
- tmpdata:/tmp
volumes:
pgdata:
driver: local
tmpdata:
driver: local
driver_opts:
type: tmpfs
device: tmpfs
# External volume (pre-existing)
existing-data:
external: true
name: my-existing-volume
Volume Plugins & NFS
# NFS volume
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.10,rw \
--opt device=:/exports/data \
nfs-volume
# Use NFS volume
docker run -v nfs-volume:/data myapp
# Popular volume plugins:
# - rexray/ebs : AWS EBS
# - cloudstor:aws : EFS / EBS
# - rexray/gcepd : GCP Persistent Disk
# - azure-file : Azure File Share
# - netshare : NFS/CIFS/S3