Bind vs Volume в Docker

Опубликовано 24 дек. 2025 г.

Сегодня рассмотрим, как и в каких случаях правильно использовать bind или volume при запуске docker контейнеров.

Пересмотрев кучу docker compose файлов, можно сделать вывод — большинство даж не понимают что они делают. Что печально, прожжённые девопс-инженеры продолжают харкодить и творить дичь. Видимо придерживаются методологии — у меня работает, остальное похуй.

ЧИТАТЬ ПЕРВЫМ В ТЕЛЕГРАМ   ЧИТАТЬ ПЕРВЫМ В MAX

Вообще есть правило:

  • Если нужно редактировать файлы руками с хоста, используешь Bind Mount.
  • Если данные нужны только приложению (БД, логи, кэш) используешь Volumes.

Шпаргалка, что есть что:

# Это docker volume, данные хранятся в
# /var/lib/docker/volumes/

volumes:
  - nginx_data:/etc/data

# Это bind mount, данные хранятся рядом
# с файлом docker-compose.yml

volumes:
  - ./data:/etc/data

Ну и никто не запрещает это совмещать, но старайся разделять. Тем более при работе с volumes, в docker есть удобные команды, ну и через midnight commander можешь физически потыкать файлы, при условии если есть рутовый доступ к файловой системе.

Самое главное не делай так:

Про этот случай я и писал в начале поста, вроде человек 20 лет отрубил в айтишке, а пишет хуйню.

volumes:
  - /home/anus/conf.d:/etc/nginx/cond.f
  - /home/anus/data/logs:/var/log/nginx

Тут идет жесткая привязка к путям и после запуска наступишь на грабли, либо получишь по ебалу от бедолаги который это запустит. Короче так не делай!

Я лично предпочитаю volumes и порой даже конфиги в нем храню, потому что этот volume можно легко примаунтить к любому другому контейнеру и получить доступ к этим файлам. Банально возьмем связку nginx + php-fpm, используем один общий volume и php скрипты корректно выполняются.

Bind mount удобен при разработке и отладки. Ты монтируешь папку с исходным кодом проекта. Правишь код в IDE на хосте и изменения мгновенно подхватываются приложением внутри контейнера.

А еще есть полезный флаг: «RO», используется в ситуациях, когда тебе нужно что-бы приложение в контейнере не перезаписывало данные в примонтированном каталоге. Удобно для отладки или для каких-то ограничений.

Пример:

services:
  web:
    image: nginx:alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./logs:/var/log/nginx

При всём желании, конфиг nginx.conf нельзя модифицировать из приложения в контейнере. Это можно сделать только на хостовой машине. Второй же bind mount по умолчанию - «RW».

Ну и пожелания:

  • Используйте именованные тома, вместо анонимных томов (которые выглядят как длинный хеш 4f32a...) всегда давайте томам осмысленные имена: db_data, app_uploads
  • Придерживайся принципа - «Один контейнер — один вольюм». Старайтесь не монтировать один и тот же вольюм в 10 разных контейнеров на запись. Если нужно делиться данными, один контейнер должен быть «владельцем» (RW), а остальные — «потребителями» (RO).
  • Бэкап: Правило «3-2-1». Volume — это не бэкап, это просто место хранения. Если ты случайно ёбнешь вольюм командой prune, данные исчезнут.

Используйте временный контейнер для создания архива:

docker run --rm -v db_data:/data -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • Docker со временем накапливает «висячие» (dangling) вольюмы — это те, что остались от удаленных контейнеров. Периодически запускай docker volume prune. Оно удалит только те тома, которые не подключены ни к одному контейнеру (включая остановленные).
  • Разницы в скорости между Bind и Volume почти нет, оба работают напрямую через ядро. Но это зависит от операционной системы, если у тебя винда и 100500 абстракций, то будут тормоза.

Вот такие пироги, если есть чё добавить, жду тебя в комментариях.

Комментарии