Artifact registry repositories

  • Tier: Premium, Ultimate
  • Offering: GitLab.com
  • Status: Beta

Use repositories to store and manage artifacts for a specific package format. A repository serves one package format and its artifacts, and you cannot nest one repository inside another.

During beta:

  • Repository visibility is set to private by default.
  • Organization members cannot view the artifact registry or its repositories without an assigned artifact registry role.

Repository types

Artifact registry supports the following repository types:

  • Hosted: Stores artifacts you publish. Use a hosted repository to push your own builds, such as the packages your CI/CD pipeline produces.
  • Remote: Proxies and caches one external registry. When a client reads from a remote repository, the request passes through to the upstream registry and the response is cached. You cannot publish to a remote repository.
  • Virtual: Combines several repositories behind one URL. Clients point at one registry instead of several. You cannot publish to a virtual repository.

Virtual repositories

Virtual repositories are in development. You can create and delete one for any format, and add upstreams to it. You can pull container images through a Docker or OCI virtual repository, Maven packages through a Maven virtual repository, and npm packages through an npm virtual repository. You cannot publish to any virtual repository.

A virtual repository uses one URL to point to multiple upstream repositories. The virtual repository organizes its upstream repositories into an ordered list.

When a client requests a package from a virtual repository, the registry walks through the list of upstreams in order until an upstream with the requested package is found.

When working with virtual registries:

  • You cannot publish to a virtual repository or to a remote repository. Both reject writes.
  • An upstream cannot be a virtual repository, and a virtual repository can hold up to 20 upstreams. Going over the limit returns a 422 Unprocessable Content error. A Maven or npm virtual repository accepts only its own format’s upstreams, and a Docker or OCI virtual repository accepts Docker and OCI upstreams alike.
  • A role assigned to a virtual repository controls read access through that repository. A role assigned to a contained repository controls direct requests to that repository.

Set the upstream list

Set the whole upstream list of a virtual repository in one request when you create or update the repository.

Prerequisites:

  • To create a virtual repository: the Artifact Admin role for the registry.
  • To update a virtual repository, or to add, move, or remove one upstream: the Artifact Manager or Artifact Admin role for the registry or the repository.
  • To read the list: the Artifact Viewer, Artifact Contributor, Artifact Manager, or Artifact Admin role for the registry or the repository.

To set the upstream list:

  • In the create or update request, send the upstream repository IDs as an array, in the order the registry checks them. The GraphQL API mutations take the array as upstreamRepositoryIds, and the management API takes it as upstream_repository_ids.

A create request must also set the repository type to virtual. A management API update of a virtual repository accepts only description, visibility, and upstream_repository_ids.

The registry treats the array as the whole list:

  • The first ID takes position 1.
  • On create, omit the list or send [] to start with no upstreams. A virtual repository with no upstreams serves no artifacts.
  • On update, the array replaces the stored list. The registry adds each ID the stored list lacks and removes each upstream the array leaves out. An upstream in both stays associated, keeps its association id, and moves to its place in the array.
  • On update, omit the list to leave it unchanged, or send [] to remove every upstream.

A rejected request changes nothing, not even the description or visibility it carries.

The create and update responses do not include the list. To read the list, query the upstreamRepositories field of organization.artifactRegistryRepository in the GraphQL API, or send a GET request to /api/v1/:handle/repositories/:repository_name/:format/upstream_repositories. The GET response is the whole list, with no pagination and no Link header. Each entry carries its association id, which the move and remove requests take as :association_id. Each entry also carries the upstream repository’s own ID as upstream_repository.id, which the array and the add request take.

An update does not check for changes that another user made to the list after you read it. The update removes an upstream they added, adds back an upstream they removed, and undoes a move they made. To add, move, or remove one upstream without that risk, send one of these requests instead:

  • Add: POST /api/v1/:handle/repositories/:repository_name/:format/upstream_repositories with upstream_repository_id, and optionally position to insert there instead of appending
  • Move: PATCH /api/v1/:handle/repositories/:repository_name/:format/upstream_repositories/:association_id with position
  • Remove: DELETE /api/v1/:handle/repositories/:repository_name/:format/upstream_repositories/:association_id

Upstream list errors

After the repository’s own fields validate, the management API checks an upstream list in this order, and stops at the first check that fails:

  • 400 Bad Request: The repository is not virtual. On create, set the type to virtual. On update, leave the list out.
  • 400 Bad Request: The value is not an array of distinct UUIDs. Send an array of distinct repository IDs, or [] for no upstreams.
  • 422 Unprocessable Content with the limit_exceeded code: The array holds more than 20 IDs. Shorten the array to 20 IDs or fewer.
  • 422 Unprocessable Content with an error.details.upstream_repository_id value: The value is the first ID in the array that cannot be an upstream. Such an ID names a repository that does not exist, is in another registry namespace, is virtual, or has a format the virtual repository does not accept. Remove or replace that ID, then send the request again.

The GraphQL mutations return the refused ID in refusedUpstreamRepositoryId.

Supported public upstreams

Remote upstream repositories can proxy the following public registries:

  • npm: Proxies npmjs.com.
  • Maven: Proxies Maven Central.
  • Docker: Proxies Docker Hub.

Caching and freshness

Setting Default What it covers
cache_validity_hours 24 hours Content files, such as npm tarballs, Maven JAR and POM files, and container tags.
metadata_cache_validity_hours 24 hours Metadata, such as maven-metadata.xml, npm package metadata documents, and npm dist-tag mappings. Applies to Maven and npm only.

Content is stale after the validity window passes following the last upstream check. A stale entry is checked against the upstream again.

Set cache_validity_hours to 0 to never revalidate. Use this setting for upstreams whose published content never changes, such as npmjs.com and Maven Central.

Setting cache_validity_hours to 0 does not turn caching off. No pass-through mode skips the cache.

metadata_cache_validity_hours must be greater than zero. Metadata has to refresh, or newly published versions never appear.

Container blobs and manifests are addressed by digest, so the registry never checks them again. The digest is the content.

Where the upstream returns an entity tag, revalidation is conditional, and only changed content is downloaded.

A stale entry with no stored entity tag is fetched in full.

Test an upstream connection

  • The test sends a HEAD request to the base URL of the upstream.
  • A scheduled check runs every five minutes with a five-second timeout.
  • A remote is marked unhealthy after three consecutive failures.
  • 2xx and 3xx responses mean healthy.
  • 401, 403, and 404 also mean healthy, because they prove the upstream is reachable.
  • Many container registries serve nothing at their root, so a healthy Docker Hub upstream commonly answers 404.
  • Only transport errors, timeouts, and 5xx responses count as failures.
  • An unhealthy upstream is skipped during virtual resolution without an outbound request.
  • A direct read against an unhealthy remote repository returns 503 with a Retry-After header.
  • A cache hit against an unhealthy remote repository is still served.

Upstream credentials

  • Maven and container upstreams take a username and password.
  • npm upstreams take an authentication token.
  • Credentials are write-only.
  • Responses show only whether credentials are set, never the values.
  • Anyone who can view the remote repository can see the upstream URL. Do not put credentials in the URL.
  • In a virtual repository’s upstream list, you see an upstream’s URL, health, visibility, and size only if you have read access to that upstream. Without it, you see the upstream’s name, format, type, and position.
  • Changing an upstream URL clears the stored credentials unless you supply new ones in the same request.
  • The response reports that the credentials were cleared.
  • Credentials scoped to the old host must not be sent to a new one.

Create a repository

To create a repository:

  1. In the left sidebar, select Artifact registry > Repositories.
  2. Select New repository, then select Hosted repository, Remote repository, or Virtual repository.
  3. From the Format dropdown list, select Docker, Maven, npm, or OCI.
  4. In the Repository name text box, enter a name. The name must:
    • Be 1 to 255 characters
    • Use lowercase letters, digits, and the characters ., _, and -
    • Start and end with a letter or digit
    • Be unique across the whole registry
  5. Optional. In the Description (optional) text box, enter a description.
  6. Optional. For a virtual repository, add its upstream repositories:
    1. Select Add repository.
    2. Search for and select one or more hosted or remote repositories of the same format, then select Add.
    3. To change the order in which the registry checks the upstreams, use the arrow buttons.
  7. Select Create repository.

After you create the repository, the format, type, and name cannot change. In the management API, the type is the kind field.

Delete a repository

In beta, repository deletion permanently removes the repository and its artifacts. If you must delete a repository, make a backup copy before you delete it.

After deletion, you cannot:

  • Restore a deleted artifact or repository.
  • See deleted content in a trash view.
  • Set a retention window or a policy that deletes content on a schedule.

Prerequisites:

  • The Artifact Admin role.

To delete a repository:

  1. In the left sidebar, select Artifact registry > Repositories.
  2. Select the repository.
  3. Select More actions ( ellipsis_v ) > Delete repository.
  4. In the Delete repository? confirmation dialog, type the repository name to confirm.
  5. Select Delete repository.

You can also delete a repository through the API.

Repository name availability after deletion

If you delete an empty repository, the name is available immediately.

If you delete a repository with artifacts, the name is available after all artifacts are removed.

Visibility

During beta, visibility is set to private for all repositories.