Skillversitas

Docker Volumes

Volumes are a way to persist data outside the container lifecycle. The data remains even after the container is deleted.

Storage Types

1. Volumes

# Create a volume
docker volume create myapp-db-data

# List volumes
docker volume ls

# Inspect a volume
docker volume inspect myapp-db-data

# Use a volume
docker run -d \
  --name db \
  -v myapp-db-data:/var/lib/postgresql/data \
  postgres:15

# Delete a volume
docker volume rm myapp-db-data

2. Bind Mounts

# Mount a host directory
docker run -d \
  --name app \
  -v /host/path:/container/path \
  myapp:latest

# Mount a specific file
docker run -d \
  --name app \
  -v /host/config.json:/app/config.json:ro \
  myapp:latest

3. Tmpfs Mounts

# Temporary mount in memory
docker run -d \
  --name app \
  --tmpfs /app/temp:rw,size=100m \
  myapp:latest

Volume Commands

# List all volumes
docker volume ls

# View volume details
docker volume inspect volume_name

# Delete unused volumes
docker volume prune

# Back up a volume
docker run --rm \
  -v myapp-db-data:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz -C /source .

# Restore a volume
docker run --rm \
  -v myapp-db-data:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/backup.tar.gz -C /target

Use Case: Application Database

# PostgreSQL with a persistent volume
docker run -d \
  --name myapp-db \
  -e POSTGRES_DB=myapp \
  -e POSTGRES_USER=admin \
  -e POSTGRES_PASSWORD=secret123 \
  -v myapp-db-data:/var/lib/postgresql/data \
  -v ./init-scripts:/docker-entrypoint-initdb.d \
  -p 5432:5432 \
  postgres:15

# Back up the database
docker exec myapp-db pg_dump -U admin myapp > backup.sql

# Restore the database
cat backup.sql | docker exec -i myapp-db psql -U admin myapp

Use Case: Development

# Run with a bind mount for development
docker run -d \
  --name dev-app \
  -v $(pwd):/app \
  -v /app/node_modules \
  -p 3000:3000 \
  node:18-alpine \
  npm run dev

Docker Compose with Volumes

version: '3.8'

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret123
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./init-scripts:/docker-entrypoint-initdb.d
    ports:
      - "5432:5432"

  api:
    build: ./backend
    environment:
      DB_HOST: db
      DB_PORT: 5432
      DB_NAME: myapp
      DB_USER: admin
      DB_PASSWORD: secret123
    volumes:
      - ./backend/src:/app/src
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  db-data:

Backup and Restore

Backup

# Back up PostgreSQL
docker exec myapp-db pg_dump -U admin myapp > backup_$(date +%Y%m%d).sql

# Back up Redis
docker exec myapp-redis redis-cli BGSAVE
docker cp myapp-redis:/data/dump.rdb ./backup_redis.rdb

Restore

# Restore PostgreSQL
cat backup.sql | docker exec -i myapp-db psql -U admin myapp

# Restore Redis
docker cp ./backup_redis.rdb myapp-redis:/data/dump.rdb
docker restart myapp-redis

Everyday Use Case

Case: A developer needs to back up data before an update.

# Back up all volumes
docker run --rm \
  -v myapp-db-data:/source:ro \
  -v $(pwd)/backups:/backup \
  alpine tar czf /backup/db_$(date +%Y%m%d).tar.gz -C /source .

# Update the application
docker-compose pull

# Restart with the data still present
docker-compose up -d

Best Practices

  1. Use named volumes: Easier to manage
  2. Back up regularly: Schedule automatic backups
  3. Delete unused volumes: docker volume prune
  4. Use bind mounts for development: For hot reload
  5. Don't use bind mounts for important data: Use named volumes

Troubleshooting

Volume not mounted

# Check permissions
ls -la /host/path

# Make sure the path is correct
docker inspect container_name | grep Mounts

Data lost after restart

# Make sure you are using a named volume
docker volume ls

# Check the mount point
docker inspect container_name | grep -A 5 "Mounts"

Conclusion

Volumes are essential for persisting data. For applications, use named volumes for databases and bind mounts for development. Back up regularly to prevent data loss.