TechLead
Lesson 5 of 18
5 min read
Docker & DevOps

Docker Volumes & Data Persistence

Master data persistence in Docker with volumes, bind mounts, and tmpfs mounts

Understanding Data Persistence

By default, data inside a container is ephemeral β€” it's lost when the container is removed. Docker provides three mechanisms for persisting data:

  • Volumes: Managed by Docker, stored in the Docker area of the host filesystem
  • Bind Mounts: Map a host directory directly into the container
  • tmpfs Mounts: Stored in host memory only (Linux), never written to disk

Docker Volumes

Volumes are the preferred way to persist data. They are fully managed by Docker and independent of the host's directory structure.

Creating and Managing Volumes

# Create a named volume
docker volume create my-data

# List all volumes
docker volume ls

# Inspect a volume
docker volume inspect my-data

# Remove a volume
docker volume rm my-data

# Remove all unused volumes
docker volume prune

Using Volumes with Containers

# Mount a named volume
docker run -d \
  --name postgres-db \
  -v pgdata:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

# Using --mount syntax (more explicit)
docker run -d \
  --name postgres-db \
  --mount source=pgdata,target=/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

# Mount as read-only
docker run -d \
  -v config:/app/config:ro \
  myapp

Bind Mounts

Bind mounts map a specific directory on the host to a directory in the container. They're great for development when you want live code reloading.

# Bind mount for development (live reload)
docker run -d \
  --name dev-app \
  -v $(pwd)/src:/app/src \
  -v $(pwd)/public:/app/public \
  -p 3000:3000 \
  myapp:dev

# Using --mount syntax
docker run -d \
  --mount type=bind,source=$(pwd)/src,target=/app/src \
  -p 3000:3000 \
  myapp:dev

# Read-only bind mount
docker run -d \
  -v $(pwd)/config:/app/config:ro \
  myapp

Practical Example: Database with Persistent Storage

# Create a volume for PostgreSQL data
docker volume create postgres-data

# Run PostgreSQL with persistent storage
docker run -d \
  --name my-postgres \
  -v postgres-data:/var/lib/postgresql/data \
  -e POSTGRES_USER=admin \
  -e POSTGRES_PASSWORD=secure123 \
  -e POSTGRES_DB=myapp \
  -p 5432:5432 \
  postgres:16

# Data survives container removal!
docker rm -f my-postgres

# Create a new container with the same volume
docker run -d \
  --name my-postgres-new \
  -v postgres-data:/var/lib/postgresql/data \
  -e POSTGRES_USER=admin \
  -e POSTGRES_PASSWORD=secure123 \
  -p 5432:5432 \
  postgres:16
# All data is still there!

Backup and Restore Volumes

# Backup a volume to a tar archive
docker run --rm \
  -v postgres-data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/postgres-backup.tar.gz -C /data .

# Restore from backup
docker run --rm \
  -v postgres-data:/data \
  -v $(pwd):/backup \
  alpine sh -c "cd /data && tar xzf /backup/postgres-backup.tar.gz"

When to Use What

  • πŸ“ Volumes: Production databases, persistent application data
  • πŸ”— Bind Mounts: Development (live code reloading), config files
  • πŸ’Ύ tmpfs: Sensitive data that should never be written to disk

Continue Learning