Dependency Proxy (FREE)

  • Introduced in GitLab 11.11.
  • Moved from GitLab Premium to GitLab Free in 13.6.
  • Introduced support for private groups in GitLab 13.7.
  • Anonymous access to images in public groups is no longer available starting in GitLab 13.7.
  • Introduced support for pull-by-digest and Docker version 20.x in GitLab 13.10.

The GitLab Dependency Proxy is a local proxy you can use for your frequently-accessed upstream images.

In the case of CI/CD, the Dependency Proxy receives a request and returns the upstream image from a registry, acting as a pull-through cache.


Supported images and packages

The following images and packages are supported.

Image/Package GitLab version
Docker 11.11+

For a list of planned additions, view the direction page.

Enable or disable the Dependency Proxy for a group

To enable or disable the Dependency Proxy for a group:

  1. Go to your group's Settings > Packages & Registries.
  2. Expand the Dependency Proxy section.
  3. To enable the proxy, turn on Enable Proxy. To disable it, turn the toggle off.

View the Dependency Proxy

To view the Dependency Proxy:

  • Go to your group's Packages & Registries > Dependency Proxy.

The Dependency Proxy is not available for projects.

Use the Dependency Proxy for Docker images

You can use GitLab as a source for your Docker images.


Authenticate with the Dependency Proxy

WARNING: This feature might not be available to you. Check the version history note above for details. The requirement to authenticate is a breaking change added in 13.7. An administrator can temporarily disable it if it has disrupted your existing Dependency Proxy usage.

Because the Dependency Proxy is storing Docker images in a space associated with your group, you must authenticate against the Dependency Proxy.

Follow the instructions for using images from a private registry, but instead of using, use your GitLab domain with no port

For example, to manually log in:

docker login --username my_username --password my_password

You can authenticate using:

Users accessing the Dependency Proxy with a personal access token or username and password require at least Guest membership to the group they pull images from.


When SSO enforcement is enabled, users must be signed-in through SSO before they can pull images through the Dependency Proxy.

Authenticate within CI/CD

  • Introduced in GitLab 13.7.
  • Automatic runner authentication, when using the Dependency Proxy to pull the image for the job, was added in GitLab 13.9.
  • The prefix for group names containing uppercase letters was fixed in GitLab 13.10.

Runners log in to the Dependency Proxy automatically. To pull through the Dependency Proxy, use one of the predefined variables:

  • CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX pulls through the top-level group.
  • CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX pulls through the subgroup, or direct group the project exists in.

Example pulling the latest alpine image:

# .gitlab-ci.yml

There are other additional predefined CI/CD variables you can also use:

  • CI_DEPENDENCY_PROXY_USER: A CI/CD user for logging in to the Dependency Proxy.
  • CI_DEPENDENCY_PROXY_PASSWORD: A CI/CD password for logging in to the Dependency Proxy.
  • CI_DEPENDENCY_PROXY_SERVER: The server for logging in to the Dependency Proxy.
  • CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: the image prefix for pulling images through the dependency proxy from the top-level group.
  • CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: the image prefix for pulling images through the dependency proxy from the direct group or subgroup that the project belongs to.

CI_DEPENDENCY_PROXY_SERVER and CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX include the server port. If you explicitly include the Dependency Proxy path, the port must be included, unless you have logged into the Dependency Proxy manually without including the port:

docker pull

Example when using the Dependency Proxy to build an image:

# Dockerfile
# .gitlab-ci.yml
image: docker:19.03.12

  DOCKER_HOST: tcp://docker:2375

  - docker:19.03.12-dind

  image: docker:19.03.12
    -  docker build -t test .

You can also use custom CI/CD variables to store and access your personal access token or deploy token.

Store a Docker image in Dependency Proxy cache

To store a Docker image in Dependency Proxy storage:

  1. Go to your group's Packages & Registries > Dependency Proxy.

  2. Copy the Dependency Proxy URL.

  3. Use one of these commands. In these examples, the image is alpine:latest.

  4. You can also pull images by digest to specify exactly which version of an image to pull.

    • Pull an image by tag by adding the image to your .gitlab-ci.yml file:

    • Pull an image by digest by adding the image to your .gitlab-ci.yml file:

      image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine@sha256:c9375e662992791e3f39e919b26f510e5254b42792519c180aad254e6b38f4dc
    • Manually pull the Docker image:

      docker pull
    • Add the URL to a Dockerfile:


GitLab pulls the Docker image from Docker Hub and caches the blobs on the GitLab server. The next time you pull the same image, GitLab gets the latest information about the image from Docker Hub, but serves the existing blobs from the GitLab server.

Reduce storage usage

Blobs are kept forever on the GitLab server, and there is no hard limit on how much data can be stored.

Using the API to clear the cache

To reclaim disk space used by image blobs that are no longer needed, use the Dependency Proxy API to clear the entire cache.

If you clear the cache, the next time a pipeline runs it must pull an image or tag from Docker Hub.

Cleanup policies

Enable cleanup policies from within GitLab

Introduced in GitLab 14.6

You can enable an automatic time-to-live (TTL) policy for the Dependency Proxy from the user interface. To do this, navigate to your group's Settings > Packages & Registries > Dependency Proxy and enable the setting to automatically clear items from the cache after 90 days.

Enable cleanup policies with GraphQL

Introduced in GitLab 14.4.

The cleanup policy is a scheduled job you can use to clear cached images that are no longer used, freeing up additional storage space. The policies use time-to-live (TTL) logic:

  • The number of days is configured.
  • All cached dependency proxy files that have not been pulled in that many days are deleted.

Use the GraphQL API to enable and configure cleanup policies:

mutation {
      groupPath: "<your-full-group-path>",
      enabled: true,
      ttl: 90
  ) {
    dependencyProxyImageTtlPolicy {

See the Getting started with GraphQL guide to learn how to make GraphQL queries.

When the policy is initially enabled, the default TTL setting is 90 days. Once enabled, stale dependency proxy files are queued for deletion each day. Deletion may not occur right away due to processing time. If the image is pulled after the cached files are marked as expired, the expired files are ignored and new files are downloaded and cached from the external registry.

Docker Hub rate limits and the Dependency Proxy

Introduced in GitLab 13.7.

Watch how to use the Dependency Proxy to help avoid Docker Hub rate limits.

In November 2020, Docker introduced rate limits on pull requests from Docker Hub. If your GitLab CI/CD configuration uses an image from Docker Hub, each time a job runs, it may count as a pull request. To help get around this limit, you can pull your image from the Dependency Proxy cache instead.

When you pull an image (by using a command like docker pull or, in a .gitlab-ci.yml file, image: foo:latest), the Docker client makes a collection of requests:

  1. The image manifest is requested. The manifest contains information about how to build the image.
  2. Using the manifest, the Docker client requests a collection of layers, also known as blobs, one at a time.

The Docker Hub rate limit is based on the number of GET requests for the manifest. The Dependency Proxy caches both the manifest and blobs for a given image, so when you request it again, Docker Hub does not have to be contacted.

How does GitLab know if a cached tagged image is stale?

If you are using an image tag like alpine:latest, the image changes over time. Each time it changes, the manifest contains different information about which blobs to request. The Dependency Proxy does not pull a new image each time the manifest changes; it checks only when the manifest becomes stale.

Docker does not count HEAD requests for the image manifest towards the rate limit. You can make a HEAD request for alpine:latest, view the digest (checksum) value returned in the header, and determine if a manifest has changed.

The Dependency Proxy starts all requests with a HEAD request. If the manifest has become stale, only then is a new image pulled.

For example, if your pipeline pulls node:latest every five minutes, the Dependency Proxy caches the entire image and only updates it if node:latest changes. So instead of having 360 requests for the image in six hours (which exceeds the Docker Hub rate limit), you only have one pull request, unless the manifest changed during that time.

Check your Docker Hub rate limit

If you are curious about how many requests to Docker Hub you have made and how many remain, you can run these commands from your runner, or even in a CI/CD script:

# Note, you must have jq installed to run this command
TOKEN=$(curl "" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "" 2>&1 | grep --ignore-case RateLimit

The output is something like:

RateLimit-Limit: 100;w=21600
RateLimit-Remaining: 98;w=21600

This example shows the total limit of 100 pulls in six hours, with 98 pulls remaining.

Check the rate limit in a CI/CD job

This example shows a GitLab CI/CD job that uses an image with jq and curl installed:

    stage: build
    image: alpine:latest
        - <optional_runner_tag>
    before_script: apk add curl jq
      - |
        TOKEN=$(curl "" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "" 2>&1


Dependency Proxy Connection Failure

If a service alias is not set the docker:19.03.12 image is unable to find the dind service, and an error like the following is thrown:

error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on no such host

This can be resolved by setting a service alias for the Docker service:

    - name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-dind
      alias: docker