Docker Volume

Volume хранит данные независимо от writable layer контейнера. Пересоздание контейнера не удаляет named volume, пока его не удалить отдельно.

Named volume и bind mount

МеханизмИсточникКогда применяю
Named volumeуправляет Dockerданные сервиса, локальная БД
Bind mountконкретный путь hostисходники и конфигурация при разработке
tmpfsпамять hostвременные чувствительные или быстрые данные

Named volume переносимее между командами запуска на одном host. Bind mount тесно связан со структурой и правами файловой системы host.

Пример

docker volume create demo-db-data
 
docker run -d \
  --name demo-db \
  -e POSTGRES_PASSWORD=example-password \
  -v demo-db-data:/var/lib/postgresql/data \
  postgres:16
 
docker volume inspect demo-db-data

После docker rm -f demo-db данные остаются. Новый совместимый контейнер можно подключить к тому же volume.

В Compose:

services:
  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data
 
volumes:
  db-data:

docker compose down обычно сохраняет declared volume; docker compose down -v удаляет project volumes и потому требует осознанного подтверждения.

Важное ограничение для БД

Один и тот же каталог данных нельзя произвольно подключать одновременно к нескольким экземплярам PostgreSQL. Volume не превращает локальную файловую систему БД в кластерное хранилище. Репликация и high availability настраиваются средствами самой БД и инфраструктуры.

Резервная копия

Копия файлов активной БД без согласования может быть неконсистентной. Предпочитаю штатный logical/physical backup базы, проверяю восстановление и только затем считаю backup рабочим.

Типичные сбои

  • Удалить volume через down -v, думая, что удаляется только контейнер.
  • Смонтировать пустой bind mount поверх каталога с файлами image и “потерять” их из вида.
  • Получить permission denied из-за UID/GID процесса.
  • Повторно использовать volume со старой несовместимой версией формата БД.
  • Считать наличие volume резервной копией.

Вопросы для собеседования

Почему volume переживает container? Это отдельный Docker object с независимым жизненным циклом.

Чем bind mount отличается от named volume? Первый указывает путь host, вторым управляет Docker.

Можно ли безопасно дать один PostgreSQL volume двум контейнерам? Не как способ масштабирования; процессы могут повредить общее хранилище.

Удаляет ли docker compose down данные? Named volumes сохраняются, если явно не запрошено их удаление; точный набор зависит от типа volume.

См. Docker, Запуск БД внутри контейнера.