Добавьте том в Docker, но исключите подпапку

Предположим, что у меня есть контейнер Docker и папка на моем хосте /hostFolder. Теперь, если я хочу добавить эту папку в контейнер Docker в качестве тома, тогда я могу сделать это, используя ADD в Dockerfile или установив его как том.

До сих пор так хорошо.

Теперь /hostFolder содержит подпапку, /hostFolder/subFolder.

Я хочу установить /hostFolder в контейнер Docker (как для чтения, так и для чтения, не имеет значения, работает для меня как для меня), но я НЕ хочу включить его /hostFolder/subFolder. Я хочу исключить это, и я также хочу, чтобы контейнер Docker мог вносить изменения в эту подпапку, без последствий ее изменения на хосте.

Возможно ли это? Если да, то как?

Ответ 1

Используя docker-compose, я могу использовать node_modules локально, но игнорировать его в контейнере докера, используя следующий синтаксис в docker-compose.yml

volumes:
   - './angularApp:/opt/app'
   - /opt/app/node_modules/

Итак, все в ./angularApp отображается на /opt/app, а затем я создаю еще один том монтирования /opt/app/node_modules/, который теперь является пустым каталогом, даже если на моей локальной машине ./angularApp/node_modules не пусто.

Ответ 2

Если вы хотите, чтобы подкаталоги игнорировались с помощью docker-compose, но сохранялись, вы можете сделать следующее в docker-compose.yml:

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules

Это смонтирует ваш текущий каталог как общий том, но монтирует постоянный уровень докеры вместо локального каталога node_modules. Это похоже на ответ @kernix, но это позволит node_modules сохраняться между прогонами docker-compose up, что, вероятно, является желаемым поведением.

Ответ 3

Чтобы исключить файл, используйте следующие

volumes:
   - /hostFolder:/folder
   - /dev/null:/folder/fileToBeExcluded

Ответ 4

Во-первых, использование команды ADD в файле Docker очень отличается от использования тома (либо с помощью аргумента -v до docker run, либо команды VOLUME в файле Docker). Команды ADD и COPY просто берут копию файлов во время выполнения docker build. Эти файлы не обновляются до тех пор, пока не будет создано новое изображение с помощью команды docker build. Напротив, использование тома в основном говорит: "Этот каталог не должен храниться в изображении контейнера, а вместо этого используйте каталог на хосте"; всякий раз, когда файл внутри тома изменяется, оба узла и контейнера сразу видят его.

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

Однако, это довольно просто, используя COPY (что должно быть предпочтительнее ADD). Вы можете использовать файл .dockerignore, чтобы исключить подкаталог, или вы могли COPY все файлы, а затем сделать RUN rm bla, чтобы удалить подкаталог.

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

Ответ 5

Похоже, что старое решение больше не работает (по крайней мере, для меня). Хотя создание пустой папки и сопоставление целевой папки с ней помогло.

volumes:
   - ./angularApp:/opt/app
   - .empty:/opt/app/node_modules/

Ответ 6

С помощью командной строки Docker:

docker run \
    --mount type=bind,src=/hostFolder,dst=/containerFolder \
    --mount type=volume,dst=/containerFolder/subFolder \
    ...other-args...

Также можно использовать опцию -v (кредит Богдану Марту), но --mount более понятен и рекомендуется.