0 --- # Meta section
...
1 project: string ! # Unique project name. More details here
2 configVersion: string ! # Config syntax version. It should always be 1 for now
3 deploy: # Settings for deployment. More details here
...
8 cleanup: # Settings for cleaning up irrelevant images. More details here
...
21 --- # Dockerfile image section: optional, define as many image sections as you need
...
22 image: string || [ string, ... ] || ~ ! # One or more unique names for image. More details here
23 dockerfile: string # Dockerfile path relative to the project directory
24 context: string # Build context PATH inside project directory (default .)
25 target: string # Specific Dockerfile stage (last one by default, see docker build --target option)
26 args: { name string: value string, ... } # Build-time variables (see docker build --build-arg option)
27 addHost: [ string, ... ] # Custom host-to-IP mapping (host:ip) (see docker build --add-host option)
28 network: string # The networking mode for the RUN instructions during build (see docker build --network option)
29 ssh: string # SSH agent socket or keys to the build (only if BuildKit enabled) (see docker build --ssh option)
30 --- # Stapel image/artifact section: optional, define as many image sections as you need
...
31 image: string || [ string, ... ] || ~ ! # One or more unique names for image. More details here
32 artifact: string # The unique name for artifact. More details here
33 from: string # The name of a base image. More details here
34 fromLatest: bool # To use actual base image without caching. More details here
35 herebyIAdmitThatFromLatestMightBreakReproducibility: bool # The confirmation of understanding the problem of using fromLatest directive. More details here
36 fromImage: string # To use image as base image by image name. More details here
37 fromArtifact: string # To use artifact as base image by artifact name. More details here
38 fromCacheVersion: string # Cache version. More details here
39 git: # Set of directives to add source files from git repositories (both the project repository and any other). More details here
...
40 url: string # The address of the remote repository. More details here
41   branch: string # The branch name. More details here
42   herebyIAdmitThatBranchMightBreakReproducibility: bool # The confirmation of understanding the problem of using branch directive. More details here
43   commit: string # The commit
44   tag: string # The tag name
45   add: string # A source path in a repository. More details here
46   to: string # A destination path in image. More details here
47   owner: string # The name or UID of the owner. More details here
48   group: string # The name or GID of the owner’s group. More details here
49   includePaths: [ string, ... ] # Masks for including. More details here
50   excludePaths: [ string, ... ] # Masks for excluding. More details here
51   stageDependencies: # The organization of restarting assembly instructions when defined changes occur in the git repository. More details here
52     install: [ string, ... ] # Masks for install stage
53     beforeSetup: [ string, ... ] # Masks for beforeSetup stage
54     setup: [ string, ... ] # Masks for setup stage
55 shell: # Shell assembly instructions. More details here
...
56   beforeInstall: [ string, ... ] # Commands for beforeInstall stage. More details here
57   install: [ string, ... ] # Commands for install stage. More details here
58   beforeSetup: [ string, ... ] # Commands for beforeSetup stage. More details here
59   setup: [ string, ... ] # Commands for setup stage. More details here
60   cacheVersion: string # Common cache version. More details here
61   beforeInstallCacheVersion: string # Cache version for beforeInstall stage. More details here
62   installCacheVersion: string # Cache version for install stage. More details here
63   beforeSetupCacheVersion: string # Cache version for beforeSetup stage. More details here
64   setupCacheVersion: string # Cache version for setup stage. More details here
65 ansible: # Ansible assembly instructions. More details here
...
66   beforeInstall: [ task, ... ] # Tasks for beforeInstall stage. More details here
67   install: [ task, ... ] # Tasks for install stage. More details here
68   beforeSetup: [ task, ... ] # Tasks for beforeSetup stage. More details here
69   setup: [ task, ... ] # Tasks for setup stage. More details here
70   cacheVersion: string # Common cache version. More details here
71   beforeInstallCacheVersion: string # Cache version for beforeInstall stage. More details here
72   installCacheVersion: string # Cache version for install stage. More details here
73   beforeSetupCacheVersion: string # Cache version for beforeSetup stage. More details here
74   setupCacheVersion: string # Cache version for setup stage. More details here
75 docker: # Set of directives to effect on an image manifest. More details here
...
76   USER: string # The user name (or UID) and optionally the user group (or GID). More details here
77   WORKDIR: string # The working directory. More details here
78   VOLUME: [ string, ... ] # Mount points. More details here
79   ENV: { name string: value string, ... } # The environment variables. More details here
80   LABEL: { name string: value string, ... } # The metadata to an image. More details here
81   EXPOSE: [ string, ... ] # To inform Docker that the container listens on the specified network ports at runtime. More details here
82   ENTRYPOINT: string # To configure a container that will run as an executable. How stapel builder processes CMD and ENTRYPOINT. More details here
83   CMD: string # To provide default arguments for the ENTRYPOINT to configure a container that will run as an executable. How stapel builder processes CMD and ENTRYPOINT. More details here
84   HEALTHCHECK: string # To tell Docker how to test a container to check that it is still working. More details here
85 mount: # Mount points. More details here
...
86 from: tmp_dir || build_dir # Service folder name
87   fromPath: string # Absolute or relative path to an arbitrary file or folder on host
88   to: string # Absolute path in image
89 import: # Imports. More details here
...
90 artifact: string # The artifact name from which you want to copy files
91   image: string # The image name from which you want to copy files
92   stage: string # The stage name from which you want to copy files (the latest one by default)
93   before: string # The stage name before which to perform importing files. At present, only install and setup stages are supported
94   after: string # The stage name after which to perform importing files. At present, only install and setup stages are supported
95   add: string # The absolute file or folder path in source image for copying
96   to: string # The absolute path in destination image. In case of absence, destination path equals source path
97   owner: string # The name or UID of the owner
98   group: string # The name or GID of the owner’s group
99   includePaths: [ string, ... ] # Masks for including
100   excludePaths: [ string, ... ] # Masks for excluding

Project name

project defines unique project name of your application. Project name affects build cache image names, Kubernetes Namespace, Helm release name and other derived names. This is a required field of meta configuration.

Project name should be unique within group of projects that shares build hosts and deployed into the same Kubernetes cluster (i.e. unique across all groups within the same gitlab). Project name must be maximum 50 chars, only lowercase alphabetic chars, digits and dashes are allowed.

Warning on changing project name

WARNING. You should never change project name, once it has been set up, unless you know what you are doing. Changing project name leads to issues:

  1. Invalidation of build cache. New images must be built. Old images must be cleaned up from local host and Docker registry manually.
  2. Creation of completely new Helm release. So if you already had deployed your application, then changed project name and deployed it again, there will be created another instance of the same application.

Werf cannot automatically resolve project name change. Described issues must be resolved manually in such case.

Deploy

Release name

werf allows to define a custom release name template, which used during deploy process to generate a release name:

project: PROJECT_NAME
configVersion: 1
deploy:
  helmRelease: TEMPLATE
  helmReleaseSlug: false

deploy.helmRelease is a Go template with [[ and ]] delimiters. There are [[ project ]], [[ env ]] functions support. Default: [[ project ]]-[[ env ]]. Template can be customized as follows:

deploy:
  helmRelease: >-
    [[ project ]]-[[ env ]]

deploy.helmReleaseSlug defines whether to apply or not slug to generated helm release name. Default: true.

Kubernetes namespace

werf allows to define a custom Kubernetes namespace template, which used during deploy process to generate a Kubernetes Namespace:

project: PROJECT_NAME
configVersion: 1
deploy:
  namespace: TEMPLATE
  namespaceSlug: true|false

deploy.namespace is a Go template with [[ and ]] delimiters. There are [[ project ]], [[ env ]] functions support. Default: [[ project ]]-[[ env ]]. Template can be customized as follows:

deploy:
  namespace: >-
    [[ project ]]-[[ env ]]

deploy.namespaceSlug defines whether to apply or not slug to generated kubernetes namespace. Default: true.

Cleanup

Configuring cleanup policies

The cleanup configuration consists of a set of policies called keepPolicies. They are used to select relevant images using the git history. Thus, during a cleanup, images not meeting the criteria of any policy are deleted.

Each policy consists of two parts:

  • references defines a set of references, git tags, or git branches to perform scanning on.
  • imagesPerReference defines the limit on the number of images for each reference contained in the set.

Each policy should be linked to some set of git tags (tag: string || /REGEXP/) or git branches (branch: string || /REGEXP/). You can specify the name/group of a reference using the Golang’s regular expression syntax.

tag: v1.1.1
tag: /^v.*$/
branch: master
branch: /^(master|production)$/

When scanning, werf searchs for the provided set of git branches in the origin remote references, but in the configuration, the origin/ prefix is omitted in branch names.

You can limit the set of references on the basis of the date when the git tag was created or the activity in the git branch. The limit group of parameters allows the user to define flexible and efficient policies for various workflows.

- references:
    branch: /^features\/.*/
    limit:
      last: 10
      in: 168h
      operator: And

In the example above, werf selects no more than 10 latest branches that have the features/ prefix in the name and have shown any activity during the last week.

  • The last: int parameter allows you to select n last references from those defined in the branch / tag.
  • The in: duration string parameter (you can learn more about the syntax in the docs) allows you to select git tags that were created during the specified period or git branches that were active during the period. You can also do that for the specific set of branches / tags.
  • The operator: And || Or parameter defines if references should satisfy both conditions or either of them (And is set by default).

When scanning references, the number of images is not limited by default. However, you can configure this behavior using the imagesPerReference set of parameters:

imagesPerReference:
  last: int
  in: duration string
  operator: And || Or
  • The last: int parameter defines the number of images to search for each reference. Their amount is unlimited by default (-1).
  • The in: duration string parameter (you can learn more about the syntax in the docs) defines the time frame in which werf searches for images.
  • The operator: And || Or parameter defines what images will stay after applying the policy: those that satisfy both conditions or either of them (And is set by default).

In the case of git tags, werf checks the HEAD commit only; the value of last>1 does not make any sense and is invalid

When describing a group of policies, you have to move from the general to the particular. In other words, imagesPerReference for a specific reference will match the latest policy it falls under:

- references:
    branch: /.*/
  imagesPerReference:
    last: 1
- references:
    branch: master
  imagesPerReference:
    last: 5

In the above example, the master reference matches both policies. Thus, when scanning the branch, the last parameter will equal to 5.

Default policies

If there are no custom cleanup policies defined in werf.yaml, werf uses default policies configured as follows:

cleanup:
  keepPolicies:
  - references:
      tag: /.*/
      limit:
        last: 10
  - references:
      branch: /.*/
      limit:
        last: 10
        in: 168h
        operator: And
    imagesPerReference:
      last: 2
      in: 168h
      operator: And
  - references:  
      branch: /^(master|staging|production)$/
    imagesPerReference:
      last: 10

Let us examine each policy individually:

  1. Keep an image for the last 10 tags (by date of creation).
  2. Keep no more than two images published over the past week, for no more than 10 branches active over the past week.
  3. Keep the 10 latest images for master, staging, and production branches.

Image section

Images are declared with image directive: image: string. The image directive starts a description for building an application image.

image: frontend

If there is only one image in the config, it can be nameless:

image: ~

In the config with multiple images, all images must have names:

image: frontend
...
---
image: backend
...

An image can have several names, set as a list in YAML syntax (this usage is equal to describing similar images with different names):

image: [main-front,main-back]

You will need an image name when setting up helm templates or running werf commands to refer to the specific image defined in the werf.yaml.

Dockerfile builder

Werf supports building images using Dockerfiles. Building image from Dockerfiles is the easiest way to start using werf in an existing project.

werf.yaml below describes an unnamed image built from Dockerfile which reside in the root of the project dir:

project: my-project
configVersion: 1
---
image: ~
dockerfile: Dockerfile

To build multiple named stages from a single Dockerfile:

image: backend
dockerfile: Dockerfile
target: backend
---
image: frontend
dockerfile: Dockerfile
target: frontend

And also build multiple images from different Dockerfiles:

image: backend
dockerfile: backend/Dockerfile
context: backend/
---
image: frontend
dockerfile: frontend/Dockerfile
context: frontend/

Stapel builder

Another alternative to building images with Dockerfiles is werf stapel builder, which is tightly integrated with Git and allows really fast incremental rebuilds on changes in the Git files.