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

231

В Dockerfile у меня есть

COPY . .

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

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

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

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

Александр Миллс
источник
23
Как насчет .dockerignore?
Энтони Соттиль
Я ищу ответ на этот связанный вопрос: 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'

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

Alex
источник
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
Вы можете создать файл в окнах, который начинается с точки, также заканчивая его точкой.
Джим Педид