Как скопировать несколько файлов в разных исходных и целевых каталогах, используя один слой COPY в Dockerfile - PullRequest
1 голос
/ 08 апреля 2019

У меня есть Dockerfile, который выглядит так:

COPY ./aaa/package.json ./aaa/package.json
COPY ./bbb/package.json ./bbb/package.json
COPY ./ccc/package.json ./ccc/package.json
WORKDIR aaa
RUN npm install
COPY ./aaa ./aaa

В основном модуль aaa использует bbb и ccc в качестве локальных модулей npm

Можно ли записать его так, чтобы первые 3 инструкции COPY выполнялись с одной инструкцией COPY, чтобы они были 1 слоем вместо 3? (Я понимаю, что есть 4-й слой с последней копией)

Мне все еще нужна последняя копия КОПИИ. Это намеренно. Причина разделения последнего слоя заключается в том, что установка npm зависит только от файлов package.json, и поэтому, если я изменяю исходный код, ему не нужно перестраивать все слои, только последний. Только если я изменю файлы package.json, потребуется перестроить первый слой и выполнить новую установку npm. Это был хороший шаблон для меня, использующего один модуль, но теперь, когда у меня есть основной модуль, который использует локальные подмодули (локальные модули npm), я застрял на том, как уменьшить количество инструкций COPY, чтобы уменьшить количество слои. Полное описание этого метода задокументировано (и рекомендуется) на сайте nodejs.org в статье «Докеризация веб-приложения Node.js»

Стоит упомянуть, что технически он работает как есть, но он неэффективен, поскольку создает дополнительные слои для дополнительных копий, когда кажется, что можно каким-то образом объединить первые три инструкции COPY для получения одного слоя.

1 Ответ

1 голос
/ 08 апреля 2019

Вы пытаетесь преобразовать это в копию многие ко многим. Это не поддерживается синтаксисом Dockerfile. Вам нужно иметь один каталог назначения на правой стороне. И если вашим источником является один или несколько каталогов, вы должны знать, что docker будет копировать содержимое этих каталогов, а не само имя каталога. В результате вы хотите:

COPY json-files/ ./

И затем вам нужно организовать ваш контекст сборки (в docker build . . или текущий каталог - это ваш контекст сборки, который отправляется на док-сервер для выполнения сборки) с каталогом под названием json-files (может быть любое имя), содержащее только те файлы в структуре каталогов, которые вы хотите скопировать:

| json-files/
|-  aaa/package.json
|-  bbb/package.json
\-  ccc/package.json

Вариант 2:

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

FROM scratch as json-files
COPY ./aaa/package.json /json-files/aaa/package.json
COPY ./bbb/package.json /json-files/bbb/package.json
COPY ./ccc/package.json /json-files/ccc/package.json

FROM your_base
COPY --from=json-files /json-files .
WORKDIR aaa
RUN npm install
COPY ./aaa ./aaa

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


Все это говорит, что изменение от 3 команд копирования до 1 для небольших отдельных файлов, которые не перезаписывают друг друга, вряд ли окажет какое-либо заметное влияние на вашу производительность, и это выглядит как преждевременная оптимизация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...