Possible to push Docker image to different repo/namespace

Is it possible to build a Docker image in one project and push it to the registry of another project?

We have a centralized project that builds different variations of the database and we want to push the image to different project (namespace). For example:

repo: database-builder

  • customerA : registry.mycompany.com/customer-a/database:latest
  • customerB: registry.mycompany.com/customer-a/database:latest

We have no issue building the image and pushing it to the registry from same repo. It seems not possible to push images to a different namespace.

$ docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
WARNING! Using --password via the CLI is insecure. Use --password-stdin.

...
Login Succeeded

... # build the image

$ docker push $FULL_IMG
The push refers to repository [registry.mycompany.com/customer-a/database:latest]
aed26e04fad5: Preparing
6dd6d5f77ec6: Preparing
...
4423957231fb: Waiting
denied: requested access to the resource is denied
Cleaning up file based variables
ERROR: Job failed: command terminated with exit code 1

I believe the generated CI_REGISTRY_USER and CI_REGISTRY_PASSWORD are only granted access to the current project you are working on.

Gitlab documents multiple other methods of authenticating with a container registry including:

  • CI_REGISTRY_USER/CI_REGISTRY_PASSWORD (what you are using)
  • CI_JOB_USER/CI_JOB_TOKEN (also likely restricted to read access from other projects but write access to current project)
  • A deploy_token. This has a “special” use case if the deploy token is for your current project and can thus access the auth from CI_DEPLOY_USER/CI_DEPLOY_PASSWORD.
  • A personal access token.

My recommendation/suggestion would be the following:

  1. Create a Deploy Token with write_registry access in your destination namespace projects. (If there are multiple destination registries, heavily consider making the Username field consistent)
  2. Add the Username and the Deploy Tokens as explicit CI/CD variables to your shared source project. i.e.
DOCKER_USER=<username for tokens in all projects>
DOCKER_PASSWORD_PROJECT_1=token
DOCKER_PASSWORD_PROJECT_2=token2
...
  1. In your .gitlab.ci.yml login and push to each registry.
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD_PROJECT_1 
- docker push $PROJECT_1_IMG_PATH
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD_PROJECT_2
- docker push $PROJECT_2_IMG_PATH

Alternatively, create a Personal Access Token for a user that has access to write to all registries and use that.