Докер сочиняет. Том внутри другого тома в том же контейнере. Как это работает?

Я пытаюсь создать относительно простую установку для разработки и тестирования пакетов npm. Проблема заключалась в том, что после монтирования тома кода в контейнер он заменяет node_modules.

Я испробовал множество в целом логических вещей, в основном направленных на перемещение node_modules в другое место, а затем на ссылку в файлах конфигурации. Это работает, но решение уродливое. Кроме того, не рекомендуется устанавливать веб-пакет глобально, но мое решение требует этого.

Однако спустя какое-то время я нашел это решение, которое выглядит элегантно, как раз то, что мне было нужно, но и у него есть одна проблема. Я не совсем понимаю, как это работает.

Это моя версия того, как все работает.

  1. Docker переупорядочивает монтирование томов на основе путей к контейнерам

  2. Docker сначала монтирует подкаталог

  3. Docker монтирует том родительского каталога, но из-за необъяснимого механизма он не переопределяет том подкаталога...

  4. ???

  5. ВЫГОДА. Директория node_modules на месте, и веб-пакет работает отлично.

Итак, я действительно хочу понять, как на самом деле работает вся эта черная магия. Потому что без этих знаний я чувствую, что упускаю что-то важное.
Итак, ребята, как это работает? Заранее спасибо.

services:
  react-generic-form:
    image: react-generic-form:package
    container_name: react-generic-form-package
    build:
      dockerfile: dev.Dockerfile
      context: ./package
    volumes:
      - "./package:/package"
      - "/package/node_modules"

Где вы находите заявление о порядке volumes: применяется?

David Maze 25.03.2019 12:49

Это просто мое логическое предположение. Эта конфигурация предотвращает удаление каталога node_modules в контейнере при монтировании родительского каталога (/package). Единственный способ сделать это — смонтировать том подпапки, который является node_modules, перед его родителем. Поэтому я думаю, что перед монтированием томов с такой конфигурацией докер сначала переупорядочивает их по их пути и монтирует подкаталоги перед их родительскими каталогами.

Nikita Balakin 25.03.2019 17:34
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
10
2
4 381
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Демон Docker при создании контейнера сортирует все точки монтирования, чтобы избежать затенения. (В не-Windows это происходит в (*github.com/docker/docker/daemon.Daemon).setupMounts.) Итак, в вашем примере:

  1. Демон Docker видит, что и /package, и /package/node_modules содержат данные, хранящиеся за пределами файлового пространства контейнера.
  2. Он сортирует эти самые короткие до самых длинных.
  3. Он монтируется /package как привязка к именованному каталогу хоста. (Во-первых, потому что это более короткий путь.)
  4. Он монтируется /package/node_modules, затеняя эквивалентный каталог в предыдущем монтировании, вероятно, как привязку к каталогу с длинным шестнадцатеричным именем где-то в /var/lib/docker/volumes.

Вы можете поэкспериментировать с этим с файлом docker-compose.yml, например

version: '3'
services:
  touch:
    image: busybox
    volumes:
      - ./b:/a/b
      - ./a:/a
    command: touch /a/b/c

Обратите внимание, что в каком бы порядке вы ни разместили volumes:, вы получите пустой каталог ./a/b (который становится точкой монтирования внутри контейнера) плюс пустой файл ./b/c (результат команды touch).

Также обратите внимание на заявление здесь о том, что каталог node_modules содержит данные, которые должны сохраняться при вызовах контейнера, и имеет жизненный цикл отдельно от контейнера или его базового образа. Изменение изображения и повторный запуск docker-compose up не повлияют на содержимое этого тома.

Вы правы, но проблема все еще здесь. Если мы смонтируем папку с хоста, который не содержит node_modules, это приведет к отсутствию node_modules в контейнере, потому что он должен переопределять содержимое папки контейнера, но не объединять его. Комментарий в коде говорит о том, что правильно, что правильно, когда вы монтируете что-то с хоста, но здесь node_modules не существует на хосте. node_modules существует в контейнере как слой изображения. Я попытался смонтировать только папку пакета, и он работает, как и ожидалось, node_modules стирается, а контейнер рушится. Итак, как объем node_modules предотвращает это?

Nikita Balakin 26.03.2019 14:34

Это фича или баг в Docker? Я просто не знаю. Кроме того, я думаю, что нашел короткое решение, которое будет работать нормально и будет логичным, но добавление одной строки в конфигурацию компоновки намного элегантнее.

Nikita Balakin 26.03.2019 14:45

Таким образом, в основном на любом другом языке обычной лучшей практикой для Docker является COPY код приложения в изображение; моей личной рекомендацией здесь было бы вообще не использовать тома.

David Maze 26.03.2019 14:46

Простое указание пути в volumes: сообщает Docker о создании анонимного тома, если это является источником вашей путаницы.

David Maze 26.03.2019 14:47

Мне нужно настроить dev env, поэтому тома — единственный способ заставить все работать, без них нет возможности сделать автокомпиляцию с просмотром файлов. В prod env все достаточно просто, код обновляется только слоем. Мне просто любопытно, потому что если я удалю анонимный том node_modules, все сломается, потому что вся папка контейнера заменяется папкой хоста, которая не содержит node_modules, а затем сборка завершается неудачно. Вопрос простой. Если том родительской папки монтируется первым, как том анонимной подпапки может предотвратить удаление подпапки контейнеров?

Nikita Balakin 26.03.2019 19:05

Другие вопросы по теме