Docker Volumes: разбираемся с монтированием

Когда начинаешь работать с Docker, то по быстрому из примеров используешь параметры монтирования с volumes, а потом не понимаешь как достучаться до файлов из файловой системы или боишься что-то не так сделать и потерять всё. Разбираемся с путницей при монтировании.

Зачем вообще нужны volumes

Начнем с того, что docker контейнер по своей природе эфемерный и изолированный, да еще и когда удаляется, то данные исчезают.

Volumes решают 2 задачи:

  1. Сохранение данных между перезапусками
  2. Доступ к файлам между хостом и контейнером

🔧 Основные способы монтирования

В Docker есть 3 основных типа:

  1. Bind mount
  2. Named volume
  3. Anonymous volume

Bind mount (прямой доступ к файловой системе)

docker run -v /home/user/app:/app

или:

docker run --mount type=bind,source=/home/user/app,target=/app

или в docker-compose

services: 
	app: 	
    	image: your-image 
		volumes: 
			- /home/user/app:/app

Ты монтируешь реальную папку с хоста внутрь контейнера.

✅ Плюсы

  • полный доступ к файлам
  • изменения видны сразу
  • удобно для разработки
  • можно редактировать файлы через IDE

❌ Минусы

  • зависит от структуры хоста
  • хуже переносимость
  • можно случайно перетереть важные данные

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

👉 Разработка (dev environment)
👉 Когда нужно иметь доступ к файлам, точно зная где папка


Named volume (управляется Docker)

docker volume create my-volume

docker run -v my-volume:/data

или в docker-compose:

services:
  app:
    volumes:
      - my-volume:/data

volumes:
  my-volume:

Docker сам хранит данные (обычно в /var/lib/docker/volumes/...).

✅ Плюсы

  • изолировано от системы
  • безопаснее
  • удобно для продакшена
  • не зависит от структуры проекта

❌ Минусы

  • нет прямого доступа как к обычной папке
  • нужно использовать Docker для просмотра

Как посмотреть файлы

docker run --rm -it -v my-volume:/data alpine sh
  • создаётся временный контейнер на базе alpine
  • volume my-volume монтируется в /data
  • открывается shell внутри контейнера
  • после выхода контейнер удаляется (--rm)

Можно работать с файлами как обычно:

ls /data
cp /data/file.txt /data/file-copy.txt

👉 Это удобный способ получить доступ к данным volume без прямого вмешательства в файловую систему Docker.

или:

docker volume inspect my-volume

Эта команда выдаст параметры volume, где можно будет найти путь к нему.

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

  • Продакшен
  • Базы данных
  • Uploads / user data

Named volume с монтированием на диск (bind через driver)

Свой текущий проект Лента Телеграм я разместил на дешевом vps с 10Гб диска и подключил внешний диск для хранения загружаемых медиафайлов (он смонитрован в /mnt/...).
Для того чтобы хранить файлы на несистемном диске можно настроить named volume с driver_opts.

Пример:

volumes:
  uploads_ext:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/blockstorage/uploads

И использовать его:

services:
  backend:
    volumes:
      - uploads_ext:/app/uploads

Хотя это выглядит как named volume, на самом деле Docker просто биндит папку /mnt/blockstorage/uploads в volume, а затем монтирует её в контейнер

✅ Плюсы

  • данные лежат на нужном диске (например, отдельный storage)
  • можно легко получить доступ через файловую систему
  • удобно для бэкапов и мониторинга
  • работает как обычный bind mount

❌ Минусы

  • теряется “изоляция” Docker
  • зависит от пути на хосте
  • нужно следить за правами доступа и наличием указанной директории

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

  • есть отдельный диск (/mnt/...)
  • нужно хранить большие файлы (uploads, медиа)
  • важен прямой доступ к данным

Anonymous volume

docker run -v /data

Docker создаёт volume без имени.

❌ Минусы

  • сложно найти
  • сложно удалить
  • легко потерять данные

Лучше не использовать, если нет конкретной причины


🧩 Ключевое отличие

ТипГде лежат файлыДоступ
bind mountфайловая система хостапрямой
named volumeвнутри Dockerчерез Docker
anonymousвнутри Dockerнеудобный

🔧 Как работать с файлами как с обычными файлами на диске

Если ты хочешь открыть файлы в IDE или редактировать их напрямую используй bind mount:

volumes:
  - ./app:/app

🔄 Dev vs Prod

Разработка:

volumes:
  - ./app:/app

✔ удобно
✔ быстро
✔ видно всё

Продакшен:

volumes:
  - uploads:/app/uploads

✔ данные сохраняются
✔ контейнеры можно пересоздавать


🔁 Как перенести данные из volume

Если нужно перейти с named volume на bind mount:

docker run --rm \
  -v uploads:/from \
  -v $(pwd)/uploads:/to \
  alpine sh -c "cp -r /from/* /to/"

Итого

  • Bind mount — для разработки и доступа к файлам
  • Named volume — для надёжного хранения данных
  • Anonymous volume — лучше избегать

Docker volumes — это не просто место для сохранения файлов, а фундамент того, как твоё приложение хранит и обрабатывает данные.

Подписывайся на мой канал Sleepless Tech, где еще больше полезных заметок про разработку.