There are several types of commands that are working with the Docker registries and require the appropriate authorization:

Supported implementations

  Build and Publish Cleanup
AWS ECR ok ok (with native API)
Azure CR ok ok (with native API)
Default ok ok
Docker Hub ok ok (with native API)
GCR ok ok
GitHub Packages ok ok (with native API and only in private GitHub repositories)
GitLab Registry ok ok
Harbor ok ok
Quay ok ok

In the near future we will add support for JFrog Container Registry and Nexus Registry

The following implementations are fully supported and do not require additional actions except docker authorization:

  • Default.
  • GCR.
  • GitLab Registry.
  • Harbor.

There are two main issues for the rest:

  1. Azure CR, AWS ECR, Docker Hub and GitHub Packages implementations provide Docker Registry API but do not implement the delete tag method and offer it with native API. Therefore, werf may require extra credentials for cleanup commands.
  2. Some implementations do not support nested repositories (Docker Hub, GitHub Packages and Quay) or support, but the user should create repositories manually using UI or API (AWS ECR). Thus, multirepo images repo mode might require specific use.

How to store images

The images repo and images repo mode params define where and how to store images (read more about image naming).

The images repo can be registry or repository address.

The resulting name of a docker image depends on the images repo mode:

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

The images are not stored in registries. Therefore, it is not acceptable to use registry as images repo and monorepo mode. Also, the user should be aware and do not use registry when using nameless image (image: ~).

Do not forget to rename nameless image in werf.yaml and delete nameless managed image (werf managed-images rm '~') if you want to use registry with multirepo images repo mode

Thus, the user has only 3 combinations of using images repo and images repo mode.

  registry + multirepo repository + monorepo repository + multirepo
AWS ECR ok ok ok
Azure CR ok ok ok
Default ok ok ok
Docker Hub ok ok not supported
GCR ok ok ok
GitHub Packages ok ok not supported
GitLab Registry ok ok ok
Harbor ok ok ok
Quay ok ok not supported

Most implementations support nested repositories and work with different images repo mode. By default, such implementations has multirepo images repo mode. The default images repo mode value for rest implementations depends on specified images repo.

AWS ECR

How to store images

Working with AWS ECR is not different from the rest implementations. The user can use both images repo modes but should manually create repositories before using werf.

How to cleanup stages and images

werf deletes tags from AWS ECR with AWS SDK. Therefore, before using cleanup commands the user should:

Azure CR

How to cleanup stages and images

The user should do the next steps to enable tag deletion with werf:

  • Install Azure CLI (az).
  • Sign in with relevant credentials (az login).

The user must have one of the following roles: Owner, Contributor or AcrDelete (more about Azure CR roles and permissions)

Docker Hub

How to store images

If you use one Docker Hub account per project and would like to store images separately you should specify account as images repo:

<ACCOUNT> # e.g. library or index.docker.io/library

Be aware that using nameless image with such an approach leads to failures and issues that are difficult to debug.

Do not forget to rename nameless image in werf.yaml and delete nameless managed image (werf managed-images rm '~') if you want to move to such an approach

If werf configuration has nameless image (image: ~) or the user want to keep all images in the single repository it is necessary to use a certain repository as images repo:

<ACCOUNT>/<REPOSITORY> # e.g. library/alpine or index.docker.io/library/alpine

Example

The user has the following:

  • Two images in werf.yaml: frontend, backend.
  • Docker Hub account: foo.

There are two ways to store these images:

  1. Images repo foo leads to foo/frontend:tag and foo/backend:tag tags.
     werf build-and-publish -s=:local -i=foo --tag-custom=tag
    
  2. Images repo foo/project leads to foo/project:frontend-tag and foo/project:backend-tag tags.
     werf build-and-publish -s=:local -i=foo/project --tag-custom=tag
    

How to cleanup stages and images

To delete tags from Docker Hub repository werf uses Docker Hub API and requires extra user credentials.

The user should specify token or username and password. The following script can be used to get the token:

HUB_USERNAME=USERNAME
HUB_PASSWORD=PASSWORD
HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${HUB_USERNAME}'", "password": "'${HUB_PASSWORD}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)

Be aware that access to the resources is forbidden with a personal access token

To define credentials check options and related environments:

  • For stages storage: --stages-storage-repo-docker-hub-token or --stages-storage-repo-docker-hub-username and --stages-storage-repo-docker-hub-password.
  • For images repo: --images-repo-docker-hub-token or --images-repo-docker-hub-username and --images-repo-docker-hub-password.
  • For both: --repo-docker-hub-token or --repo-docker-hub-username and --repo-docker-hub-password.

GitHub Packages

How to store images

If you want to keep each image in a separate package you should specify images repo without package name:

docker.pkg.github.com/<ACCOUNT>/<PROJECT> # e.g. docker.pkg.github.com/flant/werf

Be aware that using nameless image with such an approach leads to failures and issues that are difficult to debug.

Do not forget to rename nameless image in werf.yaml and delete nameless managed image (werf managed-images rm '~') if you want to move to such an approach

If werf configuration has nameless image (image: ~) or all images should be stored together use certain package:

docker.pkg.github.com/<ACCOUNT>/<PROJECT>/<PACKAGE> # e.g. docker.pkg.github.com/flant/werf/image

Example

The user has the following:

  • Two images in werf.yaml: frontend, backend.
  • GitHub repository: github.com/company/project.

There are two ways to store these images:

  1. Images repo docker.pkg.github.com/company/project leads to docker.pkg.github.com/company/project/frontend:tag and docker.pkg.github.com/company/project/backend:tag tags.
     werf build-and-publish -s=:local -i=docker.pkg.github.com/company/project --tag-custom=tag
    
  2. Images repo docker.pkg.github.com/company/project/app leads to docker.pkg.github.com/company/project/app:frontend-tag and docker.pkg.github.com/company/project/app:backend-tag tags.
     werf build-and-publish -s=:local -i=docker.pkg.github.com/company/project/app --tag-custom=tag
    

How to cleanup stages and images

To delete versions of a private package we are using GraphQL and need GitHub token with read:packages, write:packages, delete:packages and repo scopes.

Be aware that GitHub only supports deleting in private repositories

To define credentials check options and related environments:

  • For stages storage: --stages-storage-repo-github-token.
  • For images repo: --images-repo-github-token.
  • For both: --repo-github-token.

Quay

How to store images

If you want to keep each image in a separate repository you should specify images repo without repository name:

quay.io/<USER or ORGANIZATION> # e.g. quay.io/werf

Be aware that using nameless image with such an approach leads to failures and issues that are difficult to debug.

Do not forget to rename nameless image in werf.yaml and delete nameless managed image (werf managed-images rm '~') if you want to move to such an approach

If werf configuration has nameless image (image: ~) or all images should be stored together use certain repository:

quay.io/<USER or ORGANIZATION>/<REPOSITORY> # e.g. quay.io/werf/image

Example

The user has the following:

  • Two images in werf.yaml: frontend, backend.
  • quay.io organization: quay.io/company.

There are two ways to store these images:

  1. Images repo quay.io/company leads to quay.io/company/frontend:tag and quay.io/company/backend:tag tags.
     werf build-and-publish -s=:local -i=quay.io/company --tag-custom=tag
    
  2. Images repo quay.io/company/app leads to quay.io/company/app:frontend-tag and quay.io/company/app:backend-tag tags.
     werf build-and-publish -s=:local -i=quay.io/company/app --tag-custom=tag
    

Docker Authorization

werf commands do not perform authorization and use the predefined docker config to work with the Docker registry. Docker config is a directory with the authorization data for registries and other settings. By default, werf uses the same docker config as the Docker utility: ~/.docker. The Docker config directory can be redefined by setting a --docker-config option, $DOCKER_CONFIG, or $WERF_DOCKER_CONFIG environment variables. The option and variables are the same as the docker --config regular option.

To define the docker config, you can use login — the regular directive of a Docker client, or, if you are using a CI system, ci-env command in werf (learn more about how to plug werf into CI systems).

In the case of several CI jobs running simultaneously, executing docker login can lead to failed jobs because of a race condition and conflicting temporary credentials. One job affects another job by overriding temporary credentials in the Docker config. Therefore, the user should provide an individual Docker config for each job via the docker --config or by using the ci-env command instead