Чем named volume отличается от bind mount и от tmpfs? Когда что использовать?
Named volume управляется Docker и хранится в /var/lib/docker/volumes — для постоянных данных БД. Bind mount монтирует конкретный путь хоста — для hot reload кода. tmpfs живёт только в RAM и исчезает при остановке контейнера — для секретов и временных файлов.
Три типа монтирования в Docker
Docker предоставляет три механизма для работы с данными за пределами union filesystem контейнера. Выбор влияет на производительность, переносимость и безопасность.
Named Volume
Управляется Docker daemon. Физически хранится в /var/lib/docker/volumes/<name>/_data на Linux. Docker отвечает за создание директории, права доступа и жизненный цикл.
# docker-compose.yml
services:
db:
image: postgres:17
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
volumes:
pgdata: # Docker создаёт и управляет директорией
# Управление через CLI
docker volume create pgdata
docker volume ls
docker volume inspect pgdata
# Показывает Mountpoint: /var/lib/docker/volumes/pgdata/_data
# Бэкап named volume
docker run --rm \
-v pgdata:/source:ro \
-v $(pwd):/backup \
alpine tar czf /backup/pgdata.tar.gz -C /source .
Когда использовать: данные баз данных (PostgreSQL, MySQL, MongoDB), загружаемые файлы, постоянное состояние приложения. Переносим между хостами через docker volume.
Bind Mount
Монтирует конкретный путь файловой системы хоста в контейнер. Путь должен существовать до запуска контейнера (или Docker создаст директорию, но не файл).
# docker-compose.yml
services:
frontend:
image: node:22-alpine
volumes:
- ./src:/app/src # bind mount — hot reload
- ./public:/app/public # bind mount — статика
working_dir: /app
command: npm run dev
# Явный синтаксис (рекомендован для ясности)
docker run \
--mount type=bind,source=$(pwd)/config,target=/etc/myapp,readonly \
myapp:latest
# Проверка монтирований
docker inspect <container_id> | python3 -c "
import json, sys
c = json.load(sys.stdin)[0]
for m in c['Mounts']: print(m['Type'], m['Source'], '->', m['Destination'])
"
Когда использовать: разработка с hot reload, передача конфигурационных файлов, монтирование сокетов (/var/run/docker.sock), CI-кеши (Maven ~/.m2, npm node_modules).
tmpfs
Монтирует область оперативной памяти. Данные никогда не попадают на диск и уничтожаются при остановке контейнера. Поддерживается только на Linux.
# docker-compose.yml
services:
app:
image: myapp:latest
tmpfs:
- /tmp:size=64m,mode=1777
- /run:size=16m
# Через docker run
docker run \
--mount type=tmpfs,destination=/tmp,tmpfs-size=67108864 \
myapp:latest
# Или краткий синтаксис
docker run --tmpfs /tmp:size=64m myapp:latest
Когда использовать: временные файлы сессий, кеш рендеринга, файлы с чувствительными данными (токены, ключи) которые нельзя писать на диск, тесты требующие быстрого I/O.
Сравнительная таблица
- Persistence: named volume — да; bind mount — зависит от хоста; tmpfs — нет.
- Управление: named volume — Docker; bind mount — пользователь/ОС; tmpfs — kernel.
- Производительность I/O: named volume — хорошая; bind mount — зависит от ОС (на macOS медленнее); tmpfs — максимальная.
- Переносимость: named volume — высокая; bind mount — низкая (путь хоста); tmpfs — высокая (только Linux).
- Права доступа: named volume — Docker задаёт при создании; bind mount — наследует с хоста; tmpfs — задаётся параметрами.
Подводные камни
- Bind mount на macOS работает медленно из-за gRPC FUSE — горячий reload 10k файлов может тормозить. Используй
cachedилиdelegatedфлаги (Docker Desktop) или переходи наdocker compose watch. - Права доступа при bind mount. Файлы на хосте принадлежат UID хоста; внутри контейнера другой UID — получишь Permission Denied. Решение:
--userфлаг илиchownв Dockerfile. - Named volume не удаляется с контейнером.
docker compose downоставляет volumes; нужноdocker compose down -vилиdocker volume rm. - tmpfs недоступен на Windows-контейнерах. Это Linux-only механизм ядра.
- Overlay файловая система и named volume. Если контейнер пишет в путь, который уже содержит данные из образа, named volume скроет эти данные при первом монтировании (но скопирует их в volume при инициализации).
- Монтирование поверх node_modules. Bind mount
./:/appперекрывает/app/node_modulesиз образа — пакеты исчезают. Решение: добавить анонимный volume/app/node_modules. - tmpfs size не ограничен по умолчанию. Без параметра
sizetmpfs может занять всю RAM хоста.
Common mistakes
- Хранить важные данные в writable layer контейнера.
- Использовать bind mount в production без контроля host path и прав.
- Забывать, что tmpfs расходует память и не переживает restart.
What the interviewer is testing
- Различает lifecycle named volume, bind mount и tmpfs.
- Выбирает подход под data, config, dev source и temporary files.
- Учитывает backup, permissions and read-only mounts.