КОПИЯ с докером, но с исключением


231

В Dockerfile у меня есть

COPY . .

Я хочу исключить весь каталог, в моем случае, каталог node_modules.

Что-то вроде этого:

   COPY [all but **/node_modules/**] .

Это возможно с Docker?


23

Я ищу ответ на этот связанный вопрос: stackoverflow.com/questions/50547489/…
Александр Миллс

Ответы:


377

Создайте файл .dockerignoreв каталоге контекста сборки Docker (так что в этом случае, скорее всего, это каталог, являющийся родительским для node_modules) с одной строкой в ​​нем:

**/node_modules

хотя ты наверное просто хочешь

node_modules

Информация о dockerignore: https://docs.docker.com/engine/reference/builder/#dockerignore-file


5
спасибо, так что "КОПИЯ."
Александр Миллс

Не совсем: /config/nginx/ /config/logstash/я нахожу это в контейнере bash:ls config/ gunicorn logs logstash nginx
SalahAdDin

3
@SalahAdDin по той же причине, по которой вы не писали ls /config/, вы пытались добавить эти пути в ваш .dockerignore без ведущего /?
Пабло

8
Просто node_modulesне работает в подкаталогах.
rustyx

5
Это на самом деле не решает проблему, если вы хотите, чтобы она была COPY'd, но просто не в этом слое ...
Wes

33

Для тех, кто не может использовать файл .dockerignore (например, если вам нужен файл в одной копии, но не в другой):

Да, но вам нужно несколько инструкций COPY. В частности, вам нужна копия для каждой буквы в имени файла, которое вы хотите исключить.

COPY [^n]*    # All files that don't start with 'n'
COPY n[^o]*   # All files that start with 'n', but not 'no'
COPY no[^d]*  # All files that start with 'no', but not 'nod'

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


1
Это не сработает, потому что вы получите, COPY failed: no source files were specifiedкогда нет файлов, начинающихся с «нет», но не с «кивок».
mheck

1
В качестве альтернативы, вы можете использовать два разных подкаталога (для разных целей копирования), так что, например, в моей настройке nginx, я должен был src/пойти /var/wwwи /conf/nginx.confперейти к /etc/nginx/conf.d/default.conf. Кроме того, вы можете скопировать все, и RUN rm -r confпозже (тоже сохранить исходное дерево, как было). Я хотел бы услышать, если у кого-то есть другое предложение.
Юваль

1
Каково было бы решение для определенных типов файлов или окончаний файла, если бы я сделал это так?
Леа Рейманн

Единственным недостатком этого подхода является то, что структура вашей папки сглажена
Ислам Q.

Если у вас есть только несколько каталогов для копирования (скажем, только «/ app» или «/ src»). Более простым способом было бы копировать каталоги по отдельности (чтобы сохранить их структуру), а затем вам нужен только один, COPY [^node_modules]*чтобы скопировать все файлы верхнего уровня.
smdufb

9

В моем случае мой Dockerfile содержал шаг установки, на котором создавался vendorкаталог (эквивалент PHP node_modules). Я тогда COPYэтот каталог к ​​окончательному изображению приложения. Поэтому я не мог положить vendorв свой .dockerignore. Мое решение было просто удалить каталог перед выполнением composer install(эквивалент PHP npm install).

FROM composer AS composer
WORKDIR /app
COPY . .
RUN rm -rf vendor \
    && composer install 

FROM richarvey/nginx-php-fpm
WORKDIR /var/www/html
COPY --from=composer /app .

Это решение работает и не раздувает окончательный образ, но оно не идеально, потому что vendorкаталог на хосте копируется в контекст Docker во время процесса сборки, что добавляет время.


3
Обратите внимание, почему вы должны удалить, composer.lockпрежде чем composer install. Без файла блокировки при следующей сборке может быть установлен другой набор зависимостей (папка вендора).
Lacek

1
@Lacek: Вы правы. Я выучил лучше, так как я отправил это.
Кэмерон Хадсон

1
@CameronHudson, возможно, обновит ваш оригинальный ответ, прежде чем люди скопируют / вставят эту плохую практику.
Робин ван Баален

2

Добавление .dockerignore работает для меня. Еще один момент. Те, кто пробует это решение в Windows , Windows не позволят вам создать файл .dockerignore (так как он по умолчанию не позволяет создавать файл, начиная с.)

Чтобы создать такой файл, начиная с. на ОС Windows , включают в себя окончание точка также, как: .dockerignore.и нажмите клавишу ВВОД (если вы включили просматривать варианты расширения из вариантов папки)


6
Вы можете создать файл в окнах, который начинается с точки, также заканчивая его точкой.
Джим Педид

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.