Стадии импорта
import:
- image: <image name>
  stage: <stage name>
  before: <install  setup>
  after: <install  setup>
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>

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

Условный пример:

RUN “download-source && cmd && cmd2 && remove-source”

Аналогичный пример может быть реализован и в werf. Для этого достаточно описать инструкции в одной пользовательской стадии. Пример при использовании shell-сборщика для стадии install (аналогичен и для ansible-сборщика):

shell:
  install:
  - "download-source"
  - "cmd"
  - "cmd2"
  - "remove-source"

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

Другой способ — использование multi-stage сборки, которая поддерживается в Docker, начиная с версии 17.05.

FROM node:latest AS storefront
WORKDIR /app
COPY react-app .
RUN npm install
RUN npm run build

FROM maven:latest AS appserver
WORKDIR /app
COPY . .
RUN mvn package

FROM java:8-jdk-alpine
COPY --from=storefront /app/react-app/build/ /static
COPY --from=appserver /app/target/AtSea-0.0.1-SNAPSHOT.jar /app/AtSea.jar

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

werf предлагает подобный подход.

Почему werf не использует multi-stage сборку?

  • Исторически возможность импорта появилась значительно раньше, чем в Docker появилась multi-stage сборка.
  • werf дает больше гибкости при работе со вспомогательными образами.

Конфигурация импорта

Импорт ресурсов из образов должен быть описан в директиве import в конфигурации образа, куда импортируются файлы. import — массив записей, каждая из которых должна содержать следующие параметры:

  • image: <image name>: исходный образ, имя образа из которого вы хотите копировать файлы или каталоги.
  • stage: <stage name>: стадия исходного образа, определённая стадия исходного образа, из которого вы хотите копировать файлы или каталоги.
  • add: <absolute path>: исходный путь, абсолютный путь к файлу или каталогу в исходном образе для копирования.
  • to: <absolute path>: путь назначения, абсолютный путь в образе назначения (куда импортируются файлы или каталоги). В случае отсутствия считается равным значению, указанному в параметре add.
  • before: <install || setup> or after: <install || setup>: стадия образа назначения для импорта. В настоящий момент возможен импорт только до/после стадии install или setup.

Пример:

import:
- image: application-assets
  add: /app/public/assets
  to: /var/www/site/assets
  after: install
- image: frontend
  add: /app/assets
  after: setup

Так же, как и при конфигурации git mappings, поддерживаются маски включения и исключения файлов и каталогов. Для указания маски включения файлов используется параметр includePaths: [], а для исключения excludePaths: []. Маски указываются относительно пути источника (параметр add). Вы также можете указывать владельца и группу для импортируемых ресурсов с помощью параметров owner: <owner> и group: <group> соответственно. Это поведение аналогично используемому при добавлении кода из Git-репозиториев, и вы можете подробнее почитать об этом в соответствующем разделе.

Обратите внимание, что путь импортируемых ресурсов и путь указанный в git mappings не должны пересекаться.