By default, werf uses the Docker Registry API. For most container registry implementations, no other actions are required from the user.

However, the container registry may have limited support for the Docker Registry API and/or implement some functions in the native API. In this case, when using the container registry, the user may need to perform some additional actions and provide the supplementary data.

werf tries to automatically detect the type of container registry using the repository address provided (via the --repo option). The user can explicitly specify the container registry using the --repo-container-registry option or via the WERF_REPO_CONTAINER_REGISTRY environment variable.

  Build Bundles Cleanup
AWS ECR ok ok *ok
Azure CR ok ok *ok
Default ok ok ok
Docker Hub ok not supported *ok
GCR ok ok ok
GitHub Packages ok ok *ok
GitLab Registry ok ok *ok
Harbor ok ok ok
JFrog Artifactory ok ok ok
Nexus ok not tested ok
Quay ok not supported ok
Yandex Container Registry ok ok ok


When interacting with the container registry, werf commands use the information available in the Docker configuration. By default, they use the ~/.docker directory or an alternative path set by the WERF_DOCKER_CONFIG (or DOCKER_CONFIG) environment variable.

The Docker configuration is a directory where authorization data (and Docker settings) are stored (these data are used for accessing various container registries)

For authorization, you can use docker login / oras login commands as well as solutions provided by container registries.

For CI jobs, we recommend using the werf ci-env command. It creates a temporary Docker configuration based on a user configuration and performs authorization (if the container registry’s CI is used) using CI environment variables. See the relevant section of the documentation for more information about integrating werf with CI systems.

The usage of a shared Docker configuration when running parallel jobs in a CI system may lead to a job failure because of a race condition and conflicting temporary credentials (one job interferes with another by overriding temporary credentials in the shared Docker configuration). That is why we recommend creating a dedicated Docker configuration for each CI job (the werf ci-env command does this by default)


To use bundles, the container registry must support the OCI Image Format Specification.

Clean up

By default, werf uses the Docker Registry API for deleting tags. The user must be authenticated and have a sufficient set of permissions.

If the Docker Registry API isn’t supported and tags are deleted using the native API, then some additional container registry-specific actions are required on the user’s part.


werf deletes tags using the AWS SDK. Therefore, before performing a cleanup, the user must do one of the following:

Azure CR

werf deletes tags using the Azure CLI. Therefore, before performing a cleanup, the user must do the following:

  • Install the Azure CLI (az).
  • Perform authorization (az login).

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

Docker Hub

werf uses the Docker Hub API to delete tags, so you need to set either the token or the username/password pair to clean up the container registry.

You can use the following script to get a token:

HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${HUB_USERNAME}'", "password": "'${HUB_PASSWORD}'"}' | jq -r .token)

You can’t use the personal access token as a token since the deletion of resources is only possible using the user’s primary credentials.

You can use the following options (or their respective environment variables) to set the said parameters:

  • --repo-docker-hub-token or
  • --repo-docker-hub-username and --repo-docker-hub-password.

GitHub Packages

When organizing CI/CD pipelines in GitHub Actions, we recommend using our set of actions to solve most of the challenges for you.

werf uses the GitHub API to delete tags, so you need to set the token with the appropriate scopes (read:packages, delete:packages) to clean up the container registry.

You can use the --repo-github-token option or the corresponding environment variable to define the token.

GitLab Registry

werf uses the GitLab Container Registry API or Docker Registry API (depending on the GitLab version) to delete tags.

Privileges of the temporary CI job token ($CI_JOB_TOKEN) are not enough to delete tags. That is why the user have to create a dedicated token in the Access Token section (select the api in the Scope section) and perform authorization using it