Build process is a step required by werf to build images defined in the werf configuration.
Werf uses Dockerfile as a main way to describe how to build an image. Image built with Dockerfile will be referred to as dockerfile image (more info about dockerfile image).
How dockerfile image built
To build dockerfile image werf creates a single stage called
dockerfile stage is built:
- Stage signature is calculated based on specified
Dockerfileand its context. This signature represents result image state.
- If image with this signature already exists in the stages storage, then werf does not issue a new docker build.
- If image with this signature is not found in the stage storage, then werf issues a regular docker build. Werf uses usual build command of builtin docker client (same as in
docker buildcommand). Local docker cache will be created and used as usually with the regular docker client.
- After docker image is built werf puts result
dockerfilestage into stages storage (by tagging result docker image with a calculated signature when using
See configuration artictle for the werf.yaml configuration details.
Stapel image and artifact
Werf also has an alternative way to build images with so called stapel builder, which:
- Provides integration with git and incremental rebuilds based on the git repo history.
- Allows using of ansible tasks to describe instructions needed to build the image.
- Allows sharing a common cache between builds with mounts.
- Reduces image size by detaching source data and build tools.
Image built with stapel builder will be referred to as stapel image.
How stapel images and artifacts built
Each stapel image or artifact consists of a some number of stages. The same mechanics used to build every stage.
To build a stage werf generates instructions list needed to build this stage. Instructions depend on the concrete stage type and may contain internal service commands generated by werf itself along with user specified shell commands. For example werf may generate instructions to apply a prepared patch from mounted text file using git cli util.
All generated instructions to build current stage are supposed to be run in a container based on the previous stage. This container will be referred to as build container.
To build a stage werf runs prepared instructions list in the build container based on the previous stage. The resulting container state is then committed as a new stage and saved into the stages storage.
Werf has a special service image called
flant/werf-stapel which contains a chroot
/.werf/stapel with all tools and libraries needed to build images with stapel builder, such as:
- Gnu cli tools (install, patch, find, wget, grep, rsync and other).
- Git cli util.
- Python interpreter and ansible.
All these tools are compiled with an independent glibc, which allows running these tools in arbitrary environment independently of used base image.
flant/werf-stapel is mounted into every build container so that all precompiled tools are available in every stage build and may be used in instructions list.
Multiple builds on the same host
Multiple build commands can run at the same time on the same host. When building stage Werf acquires a lock using stage signature as ID so that only one build process is active for a stage with a particular signature at the same time.
When another build process is holding a lock for a stage, Werf waits until this process releases a lock. Then Werf proceeds to the next stage.
The reason is: no need to build the same stage multiple times. Werf build process can wait until another process finishes build and puts stage into the stages storage.