Модель хранения данных в 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: Временные файлы кэша, сокеты, секретные ключи во время выполнения.

Сравнительная таблица

ХарактеристикаVolumesBind Mountstmpfs
ХранилищеУправляемая зона Docker (/var/lib/docker/volumes)Любая папка на хостеОЗУ (RAM)
УправлениеDocker CLI / APIПроцессы хостаDocker (при запуске)
ВыживаемостьДа (пока не удален явно)Да (зависит от хоста)Нет (до остановки)
ПортативностьВысокаяНизкая (зависит от путей ОС)Высокая
PerformanceNative (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 нагрузок