Skip to content
intermediate Phase 94 · Docker

Docker Volumes

Docker volumes - persistent data, bind mounts, volume management

45m
0 problems
Topic Progress 0%

Volume Types

Volume Types

services:
  # Named volumes (managed by Docker)
  mysql:
    volumes:
      - mysql-data:/var/lib/mysql

  # Bind mounts (host directory)
  php-fpm:
    volumes:
      - ./src:/var/www/html
      - ./docker/php/php.ini:/usr/local/etc/php/conf.d/custom.ini

  # tmpfs mounts (temporary memory)
  mysql:
    volumes:
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 100000000

Named Volumes

volumes:
  mysql-data:
    driver: local
  redis-data:
    driver: local
  opensearch-data:
    driver: local

Bind Mounts

services:
  php-fpm:
    volumes:
      - type: bind
        source: ./src
        target: /var/www/html
      - type: bind
        source: ./docker/php/php.ini
        target: /usr/local/etc/php/conf.d/custom.ini
        read_only: true

Persistent Data Strategies

Data Persistence

services:
  mysql:
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root

  redis:
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes

  opensearch:
    volumes:
      - opensearch-data:/usr/share/opensearch/data

Data Backup Strategy

namespace Vendor\Docker\Backup;

class VolumeBackup
{
    public function backupMySQL(string $containerName): string
    {
        $backupPath = '/backups/mysql_' . date('Y-m-d_H-i-s') . '.sql';

        $command = sprintf(
            'docker exec %s mysqldump -u root -proot magento > %s',
            $containerName,
            $backupPath
        );

        exec($command, $output, $returnCode);

        return $backupPath;
    }

    public function backupRedis(string $containerName): string
    {
        $backupPath = '/backups/redis_' . date('Y-m-d_H-i-s') . '.rdb';

        $command = sprintf(
            'docker exec %s redis-cli BGSAVE && docker cp %s:/data/dump.rdb %s',
            $containerName,
            $containerName,
            $backupPath
        );

        exec($command);

        return $backupPath;
    }
}

Automated Backup Script

#!/bin/bash
# scripts/backup.sh

BACKUP_DIR="/backups/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR

# MySQL backup
docker exec mysql mysqldump -u root -proot magento | gzip > $BACKUP_DIR/mysql.sql.gz

# Redis backup
docker exec redis redis-cli BGSAVE
docker cp redis:/data/dump.rdb $BACKUP_DIR/redis.rdb

# OpenSearch backup
docker exec opensearch curl -XPOST 'localhost:9200/_snapshot/my_backup/snapshot_$(date +%Y%m%d)' -H 'Content-Type: application/json' -d '{"indices": "*"}'

Development vs Production

Development Volumes

# docker-compose.override.yml (development)
services:
  php-fpm:
    volumes:
      - ./src:/var/www/html        # Bind mount for live editing
      - ./docker/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
    environment:
      - PHP_IDE_CONFIG=serverName=docker

  nginx:
    volumes:
      - ./docker/nginx/default.dev.conf:/etc/nginx/conf.d/default.conf

Production Volumes

# docker-compose.prod.yml (production)
services:
  php-fpm:
    volumes:
      - magento-src:/var/www/html   # Named volume (read-only)
      - ./docker/php/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
    read_only: true

  mysql:
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
    secrets:
      - mysql_root_password

volumes:
  magento-src:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/magento/src

Volume Permissions

services:
  php-fpm:
    volumes:
      - ./src:/var/www/html
    user: "www-data:www-data"
    group_add:
      - "www-data"

Volume Optimization

services:
  mysql:
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_INNODB_BUFFER_POOL_SIZE: 1G
      MYSQL_INNODB_LOG_FILE_SIZE: 256M

  redis:
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes --maxmemory 256mb

Volume Management Commands

Docker Volume Commands

# List volumes
docker volume ls

# Inspect volume
docker volume inspect mysql-data

# Create volume
docker volume create my-volume

# Remove volume
docker volume rm my-volume

# Remove all unused volumes
docker volume prune

Volume Backup Commands

# Backup MySQL
docker exec mysql mysqldump -u root -proot magento > backup.sql

# Restore MySQL
docker exec -i mysql mysql -u root -proot magento < backup.sql

# Backup Redis
docker exec redis redis-cli BGSAVE
docker cp redis:/data/dump.rdb redis-backup.rdb

# Copy files from container
docker cp container:/path/to/file ./local-path

# Copy files to container
docker cp ./local-path container:/path/to/file

Volume Cleanup

# Remove stopped container volumes
docker-compose down -v

# Remove all unused volumes
docker system prune -a --volumes

# Clean specific volume
docker volume rm $(docker volume ls -q | grep old-volume)

Monitoring Volume Usage

# Check disk usage
docker system df

# Detailed volume info
docker system df -v

# Monitor volume size
watch -n 5 'docker system df'

Quiz

1. What is the difference between named volumes and bind mounts?

Question 1 options

2. Why use volumes for MySQL?

Question 2 options

3. What is a tmpfs mount?

Question 3 options

Flashcards

Question

What is a named volume?

Answer

Docker-managed persistent storage

Question

What is a bind mount?

Answer

Maps host directory to container path

Question

What is tmpfs?

Answer

Temporary in-memory storage

Question

How to backup MySQL in Docker?

Answer

docker exec mysql mysqldump > backup.sql

Revision Notes

Key Takeaways

  • 1. Named volumes are Docker-managed for persistence
  • 2. Bind mounts map host directories for development
  • 3. tmpfs mounts provide temporary in-memory storage
  • 4. Always backup database volumes regularly
  • 5. Use different volume strategies for dev vs production

Interview Tips

  • Explain named volumes vs bind mounts
  • Discuss data backup strategies
  • Describe volume permission handling
  • Talk about dev vs production volume approaches

Cheat Sheet

Volume Types:
  Named → Docker-managed persistence
  Bind → host directory mapping
  tmpfs → in-memory temporary

Backup:
  MySQL: mysqldump > backup.sql
  Redis: BGSAVE + docker cp
  OpenSearch: snapshot API

Commands:
  docker volume ls → list
  docker volume inspect → details
  docker volume prune → cleanup