import:
- artifact: <artifact name>
  image: <image 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>

The size of the image can be increased several times due to the assembly tools and source files, while the user does not need them. To solve such problems, Docker community suggests doing the installation of tools, the assembly, and removal in one step.

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

To obtain a similar effect when using werf, it is sufficient describing the instructions in one user stage. For example, shell assembly instructions for the install stage (similarly for ansible):

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

However, with this method, it is not possible using a cache, so toolkit installation runs each time.

Another solution is using multi-stage builds, which are supported starting with Docker 17.05.

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

FROM maven:latest AS appserver
WORKDIR /usr/src/atsea
COPY pom.xml .
RUN mvn -B -f pom.xml -s /usr/share/maven/ref/settings-docker.xml dependency:resolve
COPY . .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package -DskipTests

FROM java:8-jdk-alpine
RUN adduser -Dh /home/gordon gordon
WORKDIR /static
COPY --from=storefront /usr/src/atsea/app/react-app/build/ .
WORKDIR /app
COPY --from=appserver /usr/src/atsea/target/AtSea-0.0.1-SNAPSHOT.jar .
ENTRYPOINT ["java", "-jar", "/app/AtSea-0.0.1-SNAPSHOT.jar"]
CMD ["--spring.profiles.active=postgres"]

The meaning of such an approach is as follows, describe several auxiliary images and selectively copy artifacts from one image to another leaving behind everything you do not want in the result image.

We suggest the same, but using images and artifacts.

Why is werf not using multi-stage?

  • Historically, imports appeared much earlier than Docker multi-stage, and
  • Werf gives more flexibility working with auxiliary images

Importing resources from images and artifacts should be described in import directive in destination image config section (image or artifact). import is an array of records. Each record should contain the following:

  • image: <image name> or artifact: <artifact name>: source image, image name from which you want to copy files.
  • add: <absolute path>: source path, absolute file or folder path in source image for copying.
  • to: <absolute path>: destination path, absolute path in destination image. In case of absence, destination path equals source path (from add directive).
  • before: <install || setup> or after: <install || setup>: destination image stage, stage for importing files. At present, only install and setup stages are supported.
import:
- artifact: application-assets
  add: /app/public/assets
  to: /var/www/site/assets
  after: install
- image: frontend
  add: /app/assets
  after: setup

As in the case of adding git mappings, masks are supported for including, include_paths: [], and excluding files, exclude_paths: [], from the specified path. You can also define the rights for the imported resources, owner: <owner> and group: <group>. Read more about these in the git directive article.

Import paths and git mappings must not overlap with each other.

Information about using artifacts available in separate article.