null

Bind-монтирование vs Docker Volume

При работе с Docker у вас есть два способа хранения данных: bind-монтирование (bind mount) и Docker Volume. Оба позволяют контейнерам сохранять данные между перезапусками, но работают по-разному. В этой статье мы разберем их отличия, плюсы и минусы, а также рассмотрим, как изменить директорию для хранения Docker Volume.

Bind-монтирование (bind mount)

Bind-монтирование позволяет контейнеру использовать существующую директорию на хосте. Вы указываете полный путь к папке на хосте, и контейнер получает доступ к файлам внутри неё.

Синтаксис в docker-compose.yml:

services:
  my-app:
    image: my-app:latest
    volumes:
      - /var/log/my-app:/app/logs  # прямой путь к директории на хосте

Как это работает?

  • Логи приложения будут записываться в /var/log/my-app на хосте.
  • Контейнер может читать и записывать файлы в этой директории.
  • Все изменения в контейнере сразу отражаются на хосте.
  • Данные останутся после перезапуска/удаления контейнера.
  • Позволяет редактировать файлы прямо на хосте.

Например, если вы хотите, чтобы ваш nginx внутри docker-контейнера читал статические файлы прямо с директории на хосте, лучше использовать bind-монтирование:

  nginx:
    container_name: "my-nginx"
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./static:/usr/share/nginx/html/static:ro


В нашем случае, static нужен только для раздачи файлов. Флаг :ro делает директорию доступной только для чтения, исключая любые записи от nginx.

 

Docker Volume

Docker Volume — это управляемое хранилище, которое Docker создает автоматически. В отличие от bind-монтирования, volumes хранятся внутри Docker и не привязаны к конкретному пути на хосте. 

Синтаксис в docker-compose.yml:

services:
  my-app:
    image: my-app:latest
    volumes:
      - logs-volume:/app/logs  # используем Volume
volumes:
  logs-volume:  # описание тома

Отметим, что если в секции volumes не указан явный том (в нашем случае,  logs-volume), Docker автометически создаст анонимный том, которым сложнее управлять:

services:
  my-app:
    volumes:
      - /app/logs

При перезапуске контейнера этот том может быть пересоздан, что приведёт к потере данных.

Как это работает?

  • Docker сам создаёт том logs-volume в /var/lib/docker/volumes/.
  • Контейнер может использовать этот том, но он не доступен напрямую на хосте без специальных команд (docker cp для переноса данных с файловой системы контейнера на хост или docker volume inspect для получения информации о томе).
  • Данные сохраняются при перезапуске контейнера, но удаляются, если удалить том (docker volume rm logs-volume).
  • Volume используется для постоянного хранения данных внутри Docker.

 

Ключевые отличия между Docker Volume и Bind-монтированием

Особенность Docker Volume Bind-монтирование
Где хранятся данные? В /var/lib/docker/volumes/... (управляется Docker) В конкретной папке на хосте, указанной пользователем
Управление через Docker CLI docker volume create, docker volume ls, docker volume inspect Docker не управляет этими файлами
Доступность на разных ОС Работает на всех системах одинаково На Windows и Mac может требовать настройки (разные пути)
Изоляция данных Доступен только через Docker Данные сразу доступны на хосте
Производительность (на Linux) Выше, так как данные хранятся в Docker-оптимизированном месте Чуть медленнее, так как идёт работа с файловой системой хоста
Производительность (на Mac/Windows) Медленнее, так как использует виртуализацию Быстрее, потому что bind-монтирование работает напрямую
Легко ли сделать бэкап? Да (docker volume export) Нет. Нужно вручную копировать файлы
Удаление данных Данные остаются, даже если контейнер удалён Данные остаются, если папка на хосте не удалена
Гибкость Контролируется через Docker, подходит для контейнеризированных данных Позволяет использовать уже существующие файлы и папки

 

Когда что использовать?

Используйте bind-монтирование, если:

  • Нужно работать с файлами прямо на хосте, вне Docker (например, разработка и деплой).
  • Нужно монтировать конфигурационные файлы или статику (nginx, nginx.conf).
  • Файлы уже есть на хосте, и они не должны храниться в Docker.

Используйте Docker Volume, если:

  • Нужно долговременное хранение данных в Docker.
  • Данные не нужны на хосте напрямую (например, хранилище БД, MinIO, кэши).
  • Вам важна производительность (Docker оптимизирует работу с томами).
  • Нужно разделять данные между несколькими контейнерами (например, БД и бэкап-сервис).

 

Изменяем дефолтную директорию для Docker Volume

По умолчанию Docker хранит тома в /var/lib/docker/volumes/. Большой объем томов быстро заполнит системный раздел диска, что может привести к проблемам недостаточной памяти. Чтобы изменить это, нужно переопределить параметр data-root в файле конфигурации Docker:

1. Создайте новый каталог для хранения данных (например, /mnt/docker-data):

sudo mkdir -p /mnt/docker-data

2. Измените конфигурацию Docker: Откройте или создайте /etc/docker/daemon.json и добавьте:

{
  "data-root": "/mnt/docker-data"
}

3. Перезапустите Docker:

sudo systemctl restart docker

Теперь все новые тома будут храниться в /mnt/docker-data/volumes/ вместо /var/lib/docker/volumes/.