# Docker — Volumes (Хранение данных)

Эта страница объясняет, как Docker хранит постоянные данные контейнеров с помощью **Volumes**. Здесь разобраны основные типы хранения данных, команды управления volumes, а также практические примеры резервного копирования и восстановления данных. Материал рассчитан на начинающих и помогает понять, **где Docker хранит данные и как не потерять их при пересоздании контейнеров**.

---

# Что такое Docker Volume

По умолчанию контейнеры Docker **не сохраняют данные после удаления**.
Если контейнер удалить и создать заново, все файлы внутри него исчезнут.

Чтобы сохранить данные между перезапусками контейнеров, используются **Volumes**.

Volume — это специальное хранилище данных Docker, которое:

* существует независимо от контейнера
* сохраняет данные между перезапусками
* может использоваться несколькими контейнерами

---

# Почему volumes важны

Volumes используются для хранения **постоянных данных**, например:

* базы данных
* загруженные пользователями файлы
* кэш приложений
* логи

Пример:

```text
mysql container
│
└── /var/lib/mysql  → volume
```

Если контейнер удалить и создать заново, данные в volume **сохранятся**.

---

# Где Docker хранит volumes

По умолчанию volumes находятся в системе Docker:

```text
/var/lib/docker/volumes/
```

Каждый volume имеет свою директорию.

Пример структуры:

```text
/var/lib/docker/volumes/mysql_data/_data
```

---

# Типы хранения данных в Docker

Docker поддерживает несколько способов хранения данных.

---

## 1. Docker Volume

Это основной и рекомендуемый способ хранения данных.

Пример в `docker-compose.yml`:

```yaml
services:
  mysql:
    image: mysql:8
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:
```

Преимущества:

* безопасное хранение данных
* управляется Docker
* легко делать backup

---

## 2. Bind Mount

Bind mount подключает **обычную папку сервера** внутрь контейнера.

Пример:

```yaml
services:
  app:
    volumes:
      - ./src:/var/www/html
```

Это означает:

```text
сервер ./src  → контейнер /var/www/html
```

Используется для:

* разработки
* подключения исходного кода
* конфигурационных файлов

---

## Разница между Volume и Bind Mount

| Тип        | Описание              |
| ---------- | --------------------- |
| Volume     | управляется Docker    |
| Bind mount | обычная папка сервера |

Обычно используется:

* **Volumes → данные приложений**
* **Bind mounts → код проекта**

---

# Просмотр volumes

## Список volumes

```bash
docker volume ls
```

Пример вывода:

```text
DRIVER    VOLUME NAME
local     site1_mysql_data
local     redis_cache
```

---

## Информация о volume

```bash
docker volume inspect <volume_name>
```

Пример:

```bash
docker volume inspect site1_mysql_data
```

Результат покажет:

* путь к volume
* драйвер
* настройки

---

# Создание volume

Создать volume можно вручную:

```bash
docker volume create mysql_data
```

После этого volume можно использовать в контейнерах.

---

# Удаление volumes

## Удалить один volume

```bash
docker volume rm <volume>
```

Пример:

```bash
docker volume rm mysql_data
```

---

## Удалить неиспользуемые volumes

```bash
docker volume prune -f
```

Команда удаляет volumes, которые **не используются контейнерами**.

> **Важно:**
> Перед удалением нужно убедиться, что volume не содержит важных данных.

---

# Использование volumes в Docker Compose

Пример конфигурации:

```yaml
services:
  mysql:
    image: mysql:8
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:
```

Это создаёт volume `mysql_data`, который будет хранить данные базы.

---

# Проверка volumes контейнера

Можно посмотреть volumes конкретного контейнера:

```bash
docker inspect <container>
```

Пример:

```bash
docker inspect site1_mysql
```

В выводе нужно найти блок:

```text
Mounts
```

Он показывает подключённые volumes.

---

# Резервное копирование volume

Очень важная операция — backup данных.

---

## Backup volume

```bash
docker run --rm \
  -v mysql_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/mysql_backup.tar.gz /data
```

Эта команда:

1. подключает volume
2. создаёт архив
3. сохраняет backup в текущей директории

---

# Восстановление volume

Чтобы восстановить данные:

```bash
docker run --rm \
  -v mysql_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/mysql_backup.tar.gz -C /
```

После этого данные снова появятся в volume.

---

# Типичные ошибки при работе с volumes

## Потеря данных после удаления контейнера

Если данные хранятся **внутри контейнера**, а не в volume, они будут потеряны.

Правильная практика:

```yaml
volumes:
  - mysql_data:/var/lib/mysql
```

---

## Удаление volume вместе с проектом

Команда:

```bash
docker compose down -v
```

удаляет:

* контейнеры
* сети
* volumes

Это приведёт к **потере данных**.

---

## Использование bind mount для базы данных

Не рекомендуется хранить базы данных через bind mount.

Лучше использовать:

```yaml
volumes:
  - mysql_data:/var/lib/mysql
```

---

# Проверка volumes проекта

Показать volumes Compose проекта:

```bash
docker compose config --volumes
```

Это помогает понять, какие volumes использует проект.

---

# Краткая памятка

```bash
docker volume ls                    # список volumes
docker volume inspect <volume>     # информация о volume
docker volume create <volume>      # создать volume
docker volume rm <volume>          # удалить volume

docker volume prune -f             # удалить неиспользуемые volumes

docker inspect <container>         # посмотреть volumes контейнера
```