Images publish procedure

Normally in the Docker world publish process consists of the following steps:

docker tag REPO:TAG
docker push REPO:TAG
docker rmi REPO:TAG
  1. Get a name or an id of the local built image.
  2. Create new temporary image name alias for this image, which consists of two parts:
  3. Push image by newly created alias into Docker registry.
  4. Delete temporary image name alias.

To publish an image from the config Werf implements another logic:

  1. Create a new image based on built image with the specified name, store internal service information about tagging schema in this image (using docker labels). This information is referred to as image meta-information. Werf uses this information in deploy process and cleaning process.
  2. Push newly created image into Docker registry.
  3. Delete temporary image created in the 1’st step.

This procedure will be referred as images publish procedure.

The result of this procedure is an image named by the image naming rules pushed into the Docker registry. All of these steps are performed with werf publish command or werf build-and-publish command.

Images naming

During images publish procedure Werf constructs resulting images names using:

  • images repo param;
  • images repo mode param;
  • image name from werf.yaml;
  • tag param.

Resulting docker image name constructed as DOCKER_REPOSITORY:TAG.

There are images repo and images repo mode params defined where and how to store images. If werf project contains single nameless image, then images repo used as docker repository without changes and resulting docker image name costructed by the following pattern: IMAGES_REPO:TAG.

Otherwise, werf constructs resulting docker image name for each image based on images repo mode:

  • IMAGES_REPO:IMAGE_NAME-TAG pattern for monorepo mode;
  • IMAGES_REPO/IMAGE_NAME:TAG pattern for multirepo mode.

Images repo param should be specified by --images-repo option or $WERF_IMAGES_REPO.

Images repo mode param should be specified by --images-repo-mode option or $WERF_IMAGES_REPO_MODE.

Image naming behavior should be the same for publish, deploy and cleaning processes. Otherwise, the pipeline can be failed and also you can lose images and stages during the cleanup

Docker tag is taken from --tag-* params:

option description
--tag-git-tag TAG Use git-tag tagging strategy and tag by the specified git tag
--tag-git-branch BRANCH Use git-branch tagging strategy and tag by the specified git branch
--tag-git-commit COMMIT Use git-commit tagging strategy and tag by the specified git commit hash
--tag-custom TAG Use custom tagging strategy and tag by the specified arbitrary tag

All specified tag params text will be validated to confirm with the docker images tag rules. User may want to apply slug algorithm to the specified tag, see more info about slug.

Also using tag options a user specifies not only tag value but also tagging strategy. Tagging strategy affects on certain policies in cleaning process.

Every --tag-git-* option requires TAG, BRANCH or COMMIT argument. These options are designed to be compatible with modern CI/CD systems, where CI job is running in the detached git worktree for specific commit and current git-tag or git-branch or git-commit is passed to job using environment variables (for example CI_COMMIT_TAG, CI_COMMIT_REF_NAME and CI_COMMIT_SHA for Gitlab CI).

Combining parameters

Any combination of tag parameters can be used simultaneously in werf publish command or werf build-and-publish command. As a result, werf will publish a separate image for each tag parameter of each image in a project.

Examples

Two images for git tag

Given werf.yaml with 2 images — backend and frontend.

The following command:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-git-tag v1.2.0

produces the following image names respectively:

  • registry.hello.com/web/core/system/backend:v1.2.0;
  • registry.hello.com/web/core/system/frontend:v1.2.0.

Two images for git branch

Given werf.yaml with 2 images — backend and frontend.

The following command:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-git-branch my-feature-x

produces the following image names respectively:

  • registry.hello.com/web/core/system/backend:my-feature-x;
  • registry.hello.com/web/core/system/frontend:my-feature-x.

Two images for git branch with special chars in name

Given werf.yaml with 2 images — backend and frontend.

The following command:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-git-branch $(werf slugify --format docker-tag "Features/MyFeature#169")

produces the following image names respectively:

  • registry.hello.com/web/core/system/backend:features-myfeature169-3167bc8c;
  • registry.hello.com/web/core/system/frontend:features-myfeature169-3167bc8c.

Note that werf slugify command will generate a valid docker tag. See more info about slug.

Two images in Gitlab CI job

Given werf.yaml config with 2 images — backend and frontend.

The following command runs in Gitlab CI job for project named web/core/system, in the git branch named core/feature/ADD_SETTINGS, docker registry is configured as registry.hello.com/web/core/system:

type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
werf publish --stages-storage :local

Image names in the result are:

  • registry.hello.com/web/core/system/backend:core-feature-add-settings-df80fdc3;
  • registry.hello.com/web/core/system/frontend:core-feature-add-settings-df80fdc3.

Note that werf automatically applies slug to the result docker image tag: core/feature/ADD_SETTINGS will be converted to core-feature-add-settings-df80fdc3. This convertation occurs in werf ci-env command, which will determine git branch from Gitlab CI environment, automatically apply slug to this branch name and set WERF_TAG_GIT_BRANCH (which is alternative way to specify --tag-git-branch param). See more info about slug.

Unnamed image in Gitlab CI job

Given werf.yaml with single unnamed image. The following command runs in Gitlab CI job for project named web/core/queue, in the git-tag named v2.3.1, docker registry is configured as registry.hello.com/web/core/queue:

type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
werf publish --stages-storage :local

Image name in the result is registry.hello.com/web/core/queue:v2.3.1.