Docker Volumes — Persistent Data Management

Sanjeev SharmaSanjeev Sharma
5 min read

Advertisement

Docker Volumes — Persistent Data Management

Docker volumes enable persistent data storage across container lifecycle and sharing data between containers. Learn volume types and management strategies.

Introduction

Containers are ephemeral by default—data is lost when containers stop. Volumes provide the mechanism for persistent storage, enabling databases, caches, and application state to survive container restarts.

Volume Types

Docker provides three storage options:

  1. Volumes: Managed by Docker, stored in host filesystem
  2. Bind Mounts: Map host directory to container path
  3. tmpfs: In-memory storage, lost on restart

Named Volumes

Volumes managed by Docker, independent of containers.

Creating Volumes

# Create volume
docker volume create myapp_data

# List volumes
docker volume ls

# Inspect volume
docker volume inspect myapp_data

# Remove volume
docker volume rm myapp_data

# Remove unused volumes
docker volume prune

Using Volumes

# Mount volume in container
docker run -d \
  --name mydb \
  -v myapp_data:/var/lib/postgresql/data \
  postgres:15

# Volume persists after container removal
docker rm mydb

# Data still exists in volume
docker run -d \
  --name mydb2 \
  -v myapp_data:/var/lib/postgresql/data \
  postgres:15

Volumes with Docker Compose

version: '3.8'

services:
  db:
    image: postgres:15
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret

volumes:
  db_data:
    driver: local

Bind Mounts

Mount host directories into containers. Common for development.

Bind Mount Syntax

# Mount host directory
docker run -d \
  -v /host/path:/container/path \
  myapp:1.0

# Relative path (host current directory)
docker run -d \
  -v $(pwd)/data:/app/data \
  myapp:1.0

# Read-only mount
docker run -d \
  -v /host/config:/app/config:ro \
  myapp:1.0

Development Setup

# Mount source code for live editing
docker run -it \
  -v $(pwd):/app \
  -w /app \
  node:18-alpine \
  npm start

Bind Mounts in Compose

version: '3.8'

services:
  app:
    build: .
    volumes:
      # Bind mount for development
      - ./src:/app/src
      # Bind mount for logs
      - ./logs:/app/logs
      # Read-only configuration
      - ./config:/app/config:ro

Volume Drivers

Different storage backends for volumes.

Local Driver (Default)

# Create local volume
docker volume create \
  --driver local \
  myapp_data

NFS Driver

# Create NFS volume
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.1,vers=4,soft,timeo=180,bg,tcp \
  --opt device=:/export/myapp \
  myapp_nfs

Backup and Restore

Backup Volume

# Backup using tar
docker run --rm \
  -v myapp_data:/data \
  -v $(pwd):/backup \
  ubuntu \
  tar czf /backup/volume_backup.tar.gz -C /data .

# Verify backup
tar tzf volume_backup.tar.gz | head -20

Restore Volume

# Restore from backup
docker run --rm \
  -v myapp_data:/data \
  -v $(pwd):/backup \
  ubuntu \
  tar xzf /backup/volume_backup.tar.gz -C /data

# Verify restoration
docker run --rm \
  -v myapp_data:/data \
  ubuntu \
  ls -la /data

Database Backup Script

#!/bin/bash

# Backup PostgreSQL database
docker exec mydb pg_dump -U postgres mydb > db_backup.sql

# Compress backup
gzip db_backup.sql

# Move to backup directory
mv db_backup.sql.gz /backups/$(date +%Y%m%d_%H%M%S).sql.gz

# Keep only last 7 days
find /backups -name "*.sql.gz" -mtime +7 -delete

tmpfs Mounts

Temporary storage in memory, lost on container restart.

Using tmpfs

# Mount tmpfs for temporary files
docker run -d \
  --tmpfs /tmp \
  --tmpfs /run \
  myapp:1.0

# Useful for:
# - Session storage
# - Cache data
# - Temporary files
# - Security-sensitive data

Advanced Volume Management

Volume Plugins

# List installed plugins
docker plugin ls

# Use volume plugin
docker volume create \
  --driver some-plugin \
  myapp_data

Volume Inspection

# Get volume mount path
docker volume inspect myapp_data --format='{{.Mountpoint}}'

# List all volumes with paths
docker volume inspect $(docker volume ls -q) --format='{{.Name}}: {{.Mountpoint}}'

Multi-Container Data Sharing

Shared Volume

version: '3.8'

services:
  web:
    image: myapp:1.0
    volumes:
      - shared_data:/data

  worker:
    image: myworker:1.0
    volumes:
      - shared_data:/data

volumes:
  shared_data:

Data Container Pattern

# Create data container
docker create \
  --name data_container \
  -v /app/data:/data \
  ubuntu

# Mount from data container in other containers
docker run -d \
  --volumes-from data_container \
  myapp:1.0

# Multiple containers share same volume
docker run -d \
  --volumes-from data_container \
  myworker:1.0

Production Considerations

Volume Permissions

FROM postgres:15

# Ensure correct permissions
RUN chown -R postgres:postgres /var/lib/postgresql/data

Volume Size Monitoring

# Monitor volume usage
docker exec -it mydb du -sh /var/lib/postgresql/data

# Get total volume size
du -sh /var/lib/docker/volumes/myapp_data/_data

Backup Automation

version: '3.8'

services:
  db:
    image: postgres:15
    volumes:
      - db_data:/var/lib/postgresql/data

  backup:
    image: postgres:15
    entrypoint: |
      sh -c 'while true; do
        pg_dump -h db -U postgres mydb | gzip > /backups/db_$(date +\%Y\%m\%d_\%H\%M\%S).sql.gz
        find /backups -name "*.sql.gz" -mtime +7 -delete
        sleep 3600
      done'
    volumes:
      - /backups:/backups
    depends_on:
      - db

Best Practices

  1. Use named volumes for production data
  2. Back up volumes regularly with automated scripts
  3. Monitor volume usage and plan capacity
  4. Set appropriate permissions on volume directories
  5. Use bind mounts for development only
  6. Document volume lifecycle in architecture
  7. Test restore procedures regularly

FAQ

Q: Should I use volumes or bind mounts in production? A: Use named volumes in production. Bind mounts are better for development. Volumes are managed by Docker and have better portability.

Q: How do I share data between containers? A: Create a named volume and mount it in multiple containers. All containers can read/write to the shared volume.

Q: What happens if I delete a volume with running containers? A: The volume remains in use. Docker won't delete it while containers are using it. Stop containers first, then remove volumes.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro