🐳 Как смонтировать том Docker, исключив подкаталог

by itisgood

Тома Docker обеспечивают постоянное хранение данных в контейнерах.

Данные, хранящиеся в томах, хранятся независимо от контейнеров, поэтому их можно восстановить после перезагрузки или замены.

Тома поддерживают одновременное использование нескольких контейнеров, что облегчает совместное использование данных.

Монтирование тома Docker делает его содержимое доступным по определенному пути каталога внутри целевого контейнера.

Все в дереве файловой системы тома становится доступным.

Это может создать проблему, если вы хотите исключить определенные подкаталоги в данных тома.

В этой статье вы узнаете простую технику монтирования томов, избегая определенных путей.

Зачем это делать?

Поведение по умолчанию – монтирование всего тома – обычно желательно.

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

Тома также можно монтировать с помощью привязки к хосту.

🐳 Где хранятся образы, контейнеры и тома Docker в хост-системе Linux?

В этом случае каталог на вашей машине напрямую привязывается к пути внутри вашего контейнера.

Изменения, внесенные в каталог хоста, будут автоматически отражены в контейнере.

Связывающее монтирование обычно используется для ускорения разработки приложений.

Вы можете изменять исходный код и наблюдать за своими изменениями без необходимости пересборки образа Docker.

Рабочие каталоги проектов часто содержат некоторые папки, которые вы не хотите зеркалировать, например, node_modules и vendor.

Они могут уже существовать в вашем контейнере, созданные во время сборки образа.

Исключение монтирования локальных папок позволяет надежно протестировать код, используя зависимости, предоставленные в образе.

Как исключить подкаталоги из монтирования томов Docker

Подкаталоги можно исключить из монтирования тома с помощью простой техники: создайте еще одно монтирование по пути, который вы хотите игнорировать.

Если вы монтируете ~/app в /opt/app в вашем контейнере, вы можете исключить каталог ~/app/node_modules, смонтировав второй пустой том в /opt/app/node_modules:

$ docker run --name app \
    -v ~/app:/opt/app \
    -v /opt/app/node_modules \
    app-image:latest

Этот контейнер будет запускаться с содержимым каталога ~/app вашего хоста, доступного по адресу /opt/app.

Однако /opt/app/node_modules будет содержать оригинальное содержимое, предоставленное базовым образом, вместо каталога ~/app/node_modules вашего хоста.

Это работает потому, что Docker автоматически заполняет вновь созданные пустые тома существующим содержимым пути назначения, к которому они подключены.

Если вы запустили npm install как часть вашего Dockerfile, /opt/app/node_modules уже будет содержать все ваши зависимости.

Первое монтирование тома связывает каталог вашего хоста с контейнером, но второе монтирование отменяет его, создавая пустой том в /opt/app/node_modules.

Затем он заполняется файлами и папками, включенными в образ.

Порядок монтирования томов очень важен – монтирование подкаталога должно выполняться после менее конкретной привязки родителя.

В противном случае содержимое ~/app, включая его версию node_modules, будет перекрывать пустой том, предназначенный для создания исключения.

Исключение файлов

Вы можете использовать аналогичную технику для эффективного исключения отдельных файлов.

Подключение хоста /dev/null к пути к файлу приведет к тому, что он будет пустым, как будто у него нет содержимого.

$ docker run --name app \
    -v /dev/null:/opt/app/config.yaml \
    app-image:latest

Это работает только для исключения файлов – /dev/null не будет отображаться на пути к каталогам.

Метод также не работает для исключения файла с сохранением оригинальной версии из базового образа.

Он будет отображать /dev/null на путь, заменяя любой существующий файл.

Использование Docker Compose

Обе эти техники работают и в Docker Compose.

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

services:
  app:
    image: app-image:latest
    build: .
    volumes:
      - ~/app:/opt/app
      - /dev/null:/opt/app/config.yaml      # Искл. файл
      - /opt/app/node_modules               # Искл. папку
Запуск docker-compose up будет иметь тот же эффект, что и обычный пример запуска docker, показанный выше.

Заключение

При монтировании томов Docker все содержимое пути назначения контейнера заменяется содержимым каталога связанного хоста.

В некоторых ситуациях вы можете захотеть настроить это поведение, исключив из монтирования определенные пути хоста.

см. также:

 

You may also like

Leave a Comment