smhk

GitLab CI: Using a private project's container as an image

In GitLab, if you have a Container Registry set up for a private project (“Project A”), and you wish to use one of those containers in the image: field of .gitlab-ci.yml in another project (“Project B”), e.g.:

.gitlab-ci.yml
# Project B

my_stage:
    # Use container from private Project A as the image
    image: your.gitlab.address.com:5000/project_a/group/container:1.2.3
    script:
        - echo "Does something useful in container:1.2.3"

Then you may get a Failed to pull image error like the following:

Using Docker executor with image your.gitlab.address.com:5000/project_a/group/container:1.2.3 ...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image your.gitlab.address.com:5000/project_a/group/container:1.2.3 ...
WARNING: Failed to pull image with policy "always": Error response from daemon: pull access denied for your.gitlab.address.com:5000/project_a/group/container, repository does not exist or may require 'docker login': denied: requested access to the resource is denied (manager.go:205:0s)
ERROR: Job failed: failed to pull image "your.gitlab.address.com:5000/project_a/group/container:1.2.3" with specified policies [always]: Error response from daemon: pull access denied for your.gitlab.address.com:5000/project_a/group/container, repository does not exist or may require 'docker login': denied: requested access to the resource is denied (manager.go:205:0s)

The problem is that the GitLab Runner for Project B does not have permission to access Project A’s Container Registry, even if both projects are part of the same group.

You can fix this by using the DOCKER_AUTH_CONFIG variable to grant Project B’s GitLab Runner permission to pull from Project A’s Container Registry.

If you want to pull the image from within the container, for example, to use it in the FROM <image> line of a Dockerfile, then you will need to follow these steps instead. This is because the use of DOCKER_AUTH_CONFIG only grants access to the GitLab Runner, allowing it to fetch the image and launch it as a container; it does not grant access for anything running inside the container!

To set up the DOCKER_AUTH_CONFIG variable, follow these steps:

  1. On Project A (the one with the Container Registry), go to Settings > Access Tokens.
  2. Choose a token name, e.g. ci_pull_containers.
  3. Set role to “Developer”.
  4. Check the box for read_registry.
  5. Click “Create project access token”:
GitLab CI: Create project access token
  1. Generate a base64 string using these commands:
$ printf ci_pull_containers:<my_project_access_token> | openssl base64 -A
Y2lfcHVsbF9jb250YWluZXJzOm15X3Byb2plY3RfYWNjZXNzX3Rva2Vu
  1. Copy and paste the base64 string into this JSON, and replace your.gitlab.address.com:5000 with the URL and port to your GitLab instance:
{
    "auths": {
        "your.gitlab.address.com:5000": {
            "auth": "Y2lfcHVsbF9jb250YWluZXJzOm15X3Byb2plY3RfYWNjZXNzX3Rva2Vu"
        }
    }
}
  1. On Project B (the one wanting to access Projet A’s Container Registry), go to Settings > CI/CD > Variables.
  2. Click Add variable to open up a modal.
  3. Set the key as DOCKER_AUTH_CONFIG.
  4. Paste the JSON into the value field:
GitLab CI: Add variable for DOCKER_AUTH_CONFIG
  1. Click Add variable to save the new variable.
  2. That’s it! CI jobs run on Project B will now automatically use DOCKER_AUTH_CONFIG, allowing them to pull images from Project A’s Container Registry. In the GitLab CI log, this should now look like:
Using Docker executor with image your.gitlab.address.com:5000/project_a/group/container:1.2.3 ...
Authenticating with credentials from $DOCKER_AUTH_CONFIG
Pulling docker image your.gitlab.address.com:5000/project_a/group/container:1.2.3 ...
  1. Note that when the token expires you will need to create a new one and update DOCKER_AUTH_CONFIG.