При работе с 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 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/
.