There are several types of commands that are working with the Docker registries and require the appropriate authorization:
- During the building process, werf may pull base images from the Docker registry and pull/push stages in distributed builds.
- During the publishing process, werf creates and updates images in the Docker registry.
- During the cleaning process, werf deletes images and stages from the Docker registry.
- During the deploying process, werf requires access to the images from the Docker registry and to the stages that could also be stored in the Docker registry.
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 |
JFrog Artifactory | ok | ok |
Quay | ok | ok |
In the nearest future we will add support for 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:
- 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.
- 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 |
JFrog Artifactory | 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:
- Set up AWS CLI installation (
aws configure
) or - Define
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
environment variables.
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
orAcrDelete
(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:
- Images repo foo leads to
foo/frontend:tag
andfoo/backend:tag
tags.werf build-and-publish -s=:local -i=foo --tag-custom=tag
- Images repo foo/project leads to
foo/project:frontend-tag
andfoo/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:
- Images repo docker.pkg.github.com/company/project leads to
docker.pkg.github.com/company/project/frontend:tag
anddocker.pkg.github.com/company/project/backend:tag
tags.werf build-and-publish -s=:local -i=docker.pkg.github.com/company/project --tag-custom=tag
- Images repo docker.pkg.github.com/company/project/app leads to
docker.pkg.github.com/company/project/app:frontend-tag
anddocker.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:
- Images repo quay.io/company leads to
quay.io/company/frontend:tag
andquay.io/company/backend:tag
tags.werf build-and-publish -s=:local -i=quay.io/company --tag-custom=tag
- Images repo quay.io/company/app leads to
quay.io/company/app:frontend-tag
andquay.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 thedocker --config
or by using theci-env
command instead