Модель хранения данных в Docker
TL;DR: Данные в контейнере — эфемерны. Для персистентности: Volumes (production), Bind Mounts (разработка), tmpfs (секреты/кэш в RAM).
По умолчанию данные внутри контейнера эфемерны. Они хранятся в записываемом слое (Container Layer) и жестко привязаны к жизненному циклу самого контейнера. Если контейнер будет удален (docker rm), данные исчезнут вместе с ним.
Для сохранения данных (persistence) и обмена информацией между контейнером и хостом Docker предлагает три основных механизма монтирования.
1. Volumes (Тома)
Volumes — это предпочтительный механизм для хранения данных в Docker. Они полностью управляются Docker-ом.
- Расположение: Хранятся в специальной директории на хосте, контролируемой Docker (в Linux обычно
/var/lib/docker/volumes/). Пользователю не следует трогать эти файлы напрямую. - Управление: Создаются и удаляются через CLI (
docker volume create/rm) или декларативно в Compose. - Независимость: Volume может существовать отдельно от контейнера. Данные выживают даже после удаления контейнера, к которому был примонтирован том.
Преимущества Volumes:
- Портативность: Работают одинаково на Linux, Windows и macOS.
- Производительность: На macOS/Windows (Docker Desktop) работают быстрее, чем Bind Mounts, так как находятся внутри VM Linux.
- Безопасность: Изолированы от остальной файловой системы хоста.
- Драйверы: Поддерживают Volume Drivers для хранения данных в облаке (S3, Azure File Storage) или на удаленных серверах (NFS), прозрачно для приложения.
Use Case: Базы данных (Postgres, Mongo), хранение логов, статические ассеты, которые должны пережить пересоздание контейнера.
2. Bind Mounts (Привязка директорий)
Bind Mounts монтируют произвольную директорию или файл с хост-системы внутрь контейнера.
- Расположение: Любой путь на хосте (например,
/home/user/projectилиC:\Users\Project). - Зависимость от хоста: Пути жестко привязаны к структуре файловой системы хоста. Это снижает портативность (путь
/home/userне сработает на Windows или на сервере с другой структурой). - Доступ: Процессы на хосте и в контейнере могут одновременно менять файлы.
Проблема прав доступа (Permissions Hell)
В Linux Bind Mounts просто пробрасывают файлы с сохранением их UID/GID.
- Если процесс в контейнере работает от
root(UID 0), файлы на хосте, созданные им, будут принадлежатьroot. У пользователя на хосте может пропасть доступ к этим файлам. - Если процесс в контейнере работает от пользователя
node(UID 1000), а папка на хосте принадлежитroot, контейнер получит ошибкуPermission Denied.
Use Case: Локальная разработка. Вы монтируете исходный код (
./src:/app/src), чтобы изменения на хосте мгновенно попадали в контейнер (Hot Reload), не требуя пересборки образа.
3. tmpfs Mounts
tmpfs хранит данные только в оперативной памяти хоста. Данные никогда не записываются на диск.
- Эфемерность: Данные теряются при остановке контейнера.
- Скорость: Максимально возможная скорость чтения/записи.
- Безопасность: Полезно для хранения секретов (ключей, токенов), которые не должны остаться на диске даже в зашифрованном виде.
Use Case: Временные файлы кэша, сокеты, секретные ключи во время выполнения.
Сравнительная таблица
| Характеристика | Volumes | Bind Mounts | tmpfs |
|---|---|---|---|
| Хранилище | Управляемая зона Docker (/var/lib/docker/volumes) | Любая папка на хосте | ОЗУ (RAM) |
| Управление | Docker CLI / API | Процессы хоста | Docker (при запуске) |
| Выживаемость | Да (пока не удален явно) | Да (зависит от хоста) | Нет (до остановки) |
| Портативность | Высокая | Низкая (зависит от путей ОС) | Высокая |
| Performance | Native (Linux), High (Mac/Win) | Native (Linux), Slow (Mac/Win) | Ultra High |
| Основное назначение | Production (БД, данные) | Development (код) | Security / Temp Cache |
Copy-on-Write vs Volumes
Важно помнить архитектурное различие:
- Без тома: Запись идет в Container Layer через драйвер OverlayFS (CoW). Это накладные расходы на копирование файлов из нижних слоев.
- С томом (Volume/Bind): Механизм OverlayFS/CoW отключается для точки монтирования. Запись идет напрямую на диск хоста. Поэтому для баз данных Volumes обязательны не только для сохранности, но и для производительности (I/O throughput).
Подводные камни
| Заблуждение | Реальность |
|---|---|
| «docker rm не удалит мои данные» | Без volume данные в container layer удаляются вместе с контейнером |
| «Bind mount = volume» | Bind mount зависит от путей хоста и имеет проблемы с правами (UID/GID mismatch) |
| «Volume работает быстро на macOS» | Быстрее bind mount, но медленнее native Linux (из-за VM-прослойки Docker Desktop) |
| «БД можно запускать без volume» | Без volume данные теряются. Плюс CoW даёт деградацию I/O для write-heavy нагрузок |