컨테이너 레지스트리 API

Tier: Free, Premium, Ultimate
Offering: GitLab.com, Self-managed, GitLab Dedicated
  • CI/CD 작업 토큰으로 인증 기능은 GitLab 13.12에서 ci_job_token_scope라는 플래그로 도입되었습니다. 기본적으로 비활성화됨.
  • CI/CD 작업 토큰 인증은 GitLab 16.8에서 일반 사용 가능합니다. 피처 플래그 ci_job_token_scope가 제거되었습니다.

이 API 엔드포인트를 사용하여 GitLab 컨테이너 레지스트리 작업을 수행할 수 있습니다.

CI/CD 작업에서 이 엔드포인트로 $CI_JOB_TOKENJOB-TOKEN 헤더로 전달하여 인증할 수 있습니다. 작업 토큰은 파이프라인을 생성한 프로젝트의 컨테이너 레지스트리에만 액세스 권한이 있습니다.

컨테이너 레지스트리의 가시성 변경

  • GitLab 14.2에서 도입되었습니다.

이것은 컨테이너 레지스트리를 볼 수 있는 사용자를 제어합니다.

PUT /projects/:id/
속성 유형 필수 설명
id 정수/문자열 인증된 사용자가 액세스할 수 있는 프로젝트의 ID 또는 URL 인코딩된 경로
container_registry_access_level 문자열 아니요 컨테이너 레지스트리의 원하는 가시성. enabled(기본값), private, 또는 disabled 중 하나입니다.

container_registry_access_level의 가능한 값을 설명:

  • enabled (기본값): 프로젝트에 액세스 권한이 있는 모든 사람이 컨테이너 레지스트리를 볼 수 있습니다. 프로젝트가 공개되어 있으면 컨테이너 레지스트리도 공개됩니다. 프로젝트가 내부 또는 비공개이면 컨테이너 레지스트리도 내부 또는 비공개입니다.
  • private: 컨테이너 레지스트리는 리포터 역할 이상의 프로젝트 구성원만 볼 수 있습니다. 이 동작은 컨테이너 레지스트리 가시성이 enabled로 설정된 개인 프로젝트와 유사합니다.
  • disabled: 컨테이너 레지스트리가 비활성화됩니다.

사용자에게이 설정이 부여하는 권한에 대한 자세한 내용은 컨테이너 레지스트리 가시성 권한을 참조하세요.

curl --request PUT "https://gitlab.example.com/api/v4/projects/5/" \
     --header 'PRIVATE-TOKEN: <your_access_token>' \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --data-raw '{
         "container_registry_access_level": "private"
     }'

예시 응답:

{
  "id": 5,
  "name": "프로젝트 5",
  "container_registry_access_level": "private",
  ...
}

컨테이너 레지스트리 페이징

기본적으로 GET 요청은 분할되어 있기 때문에 한 번에 20개의 결과를 반환합니다.

레지스트리 리포지터리 디렉터리

프로젝트 내에서

프로젝트 내에서 레지스트리 리포지터리 디렉터리을 가져옵니다.

GET /projects/:id/registry/repositories
속성 유형 필수 설명
id 정수/문자열 인증된 사용자가 액세스할 수 있는 프로젝트의 ID 또는 URL 인코딩된 경로
tags 부울 아니요 매개변수가 true로 포함되면 각 리포지터리에 응답본에 "tags" 배열이 포함됩니다.
tags_count 부울 아니요 매개변수가 true로 포함되면 각 리포지터리에 "tags_count"가 응답본에 포함됩니다(GitLab 13.1에서 도입).
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories"

예시 응답:

[
  {
    "id": 1,
    "name": "",
    "path": "group/project",
    "project_id": 9,
    "location": "gitlab.example.com:5000/group/project",
    "created_at": "2019-01-10T13:38:57.391Z",
    "cleanup_policy_started_at": "2020-01-10T15:40:57.391Z",
    "status": null
  },
  {
    "id": 2,
    "name": "릴리스",
    "path": "group/project/releases",
    "project_id": 9,
    "location": "gitlab.example.com:5000/group/project/releases",
    "created_at": "2019-01-10T13:39:08.229Z",
    "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z",
    "status": "delete_ongoing"
  }
]

그룹 내에서

  • GitLab 15.0에서 tagstag_count 속성이 제거되었습니다.

그룹 내에서 레지스트리 리포지터리 디렉터리을 가져옵니다.

GET /groups/:id/registry/repositories
속성 유형 필수 설명
id 정수/문자열 인증된 사용자가 액세스할 수 있는 그룹의 ID 또는 URL 인코딩된 경로
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/groups/2/registry/repositories"

예시 응답:

[
  {
    "id": 1,
    "name": "",
    "path": "group/project",
    "project_id": 9,
    "location": "gitlab.example.com:5000/group/project",
    "created_at": "2019-01-10T13:38:57.391Z",
    "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z",
  },
  {
    "id": 2,
    "name": "",
    "path": "group/other_project",
    "project_id": 11,
    "location": "gitlab.example.com:5000/group/other_project",
    "created_at": "2019-01-10T13:39:08.229Z",
    "cleanup_policy_started_at": "2020-01-10T15:40:57.391Z",
  }
]

단일 리포지터리 세부 정보 가져오기

레지스트리 리포지터리의 세부 정보를 가져옵니다.

GET /registry/repositories/:id
속성 유형 필수 여부 설명
id 정수/문자열 인증된 사용자가 액세스할 수 있는 레지스트리 리포지터리의 ID입니다.
tags 부울 아니요 매개변수를 true로 포함하면 응답에 "tags" 배열이 포함됩니다.
tags_count 부울 아니요 매개변수를 true로 포함하면 응답에 "tags_count"가 포함됩니다.
size 부울 아니요 매개변수를 true로 포함하면 응답에 "size"가 포함됩니다. 이것은 리포지터리 내 모든 이미지의 중복 제거 크기입니다. 중복 제거는 동일한 데이터의 추가 복사본을 제거합니다. 예를 들어, 동일한 이미지를 두 번 업로드하면 컨테이너 레지스트리에는 하나의 복사본만 저장됩니다. 이 필드는 2021-11-04 이후에 생성된 리포지터리에 대해서만 GitLab.com에서만 사용할 수 있습니다.
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/registry/repositories/2?tags=true&tags_count=true&size=true"

예시 응답:

{
  "id": 2,
  "name": "",
  "path": "group/project",
  "project_id": 9,
  "location": "gitlab.example.com:5000/group/project",
  "created_at": "2019-01-10T13:38:57.391Z",
  "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z",
  "tags_count": 1,
  "tags": [
    {
      "name": "0.0.1",
      "path": "group/project:0.0.1",
      "location": "gitlab.example.com:5000/group/project:0.0.1"
    }
  ],
  "size": 2818413,
  "status": "delete_scheduled"
}

레지스트리 리포지터리 삭제

레지스트리에서 리포지터리를 삭제합니다.

이 작업은 비동기적으로 실행되며 실행에 시간이 소요될 수 있습니다.

DELETE /projects/:id/registry/repositories/:repository_id
속성 유형 필수 여부 설명
id 정수/문자열 인증된 사용자가 소유한 프로젝트의 ID 또는 URL 인코딩된 경로입니다.
repository_id 정수 레지스트리 리포지터리의 ID입니다.
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2"

레지스트리 리포지터리 태그 디렉터리

프로젝트 내에서

주어진 레지스트리 리포지터리의 태그 디렉터리을 가져옵니다.

GET /projects/:id/registry/repositories/:repository_id/tags
속성 유형 필수 여부 설명
id 정수/문자열 인증된 사용자가 액세스할 수 있는 프로젝트의 ID 또는 URL 인코딩된 경로입니다.
repository_id 정수 레지스트리 리포지터리의 ID입니다.
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"

예시 응답:

[
  {
    "name": "A",
    "path": "group/project:A",
    "location": "gitlab.example.com:5000/group/project:A"
  },
  {
    "name": "latest",
    "path": "group/project:latest",
    "location": "gitlab.example.com:5000/group/project:latest"
  }
]

레지스트리 리포지터리 태그의 세부 정보 가져오기

레지스트리 리포지터리의 태그 세부 정보를 가져옵니다.

GET /projects/:id/registry/repositories/:repository_id/tags/:tag_name
속성 유형 필수 여부 설명
id 정수/문자열 인증된 사용자가 액세스할 수 있는 프로젝트의 ID 또는 URL 인코딩된 경로입니다.
repository_id 정수 레지스트리 리포지터리의 ID입니다.
tag_name 문자열 태그의 이름입니다.
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags/v10.0.0"

예시 응답:

{
  "name": "v10.0.0",
  "path": "group/project:latest",
  "location": "gitlab.example.com:5000/group/project:latest",
  "revision": "e9ed9d87c881d8c2fd3a31b41904d01ba0b836e7fd15240d774d811a1c248181",
  "short_revision": "e9ed9d87c",
  "digest": "sha256:c3490dcf10ffb6530c1303522a1405dfaf7daecd8f38d3e6a1ba19ea1f8a1751",
  "created_at": "2019-01-06T16:49:51.272+00:00",
  "total_size": 350224384
}

레지스트리 리포지터리 태그 삭제하기

레지스트리 리포지터리의 태그를 삭제합니다.

DELETE /projects/:id/registry/repositories/:repository_id/tags/:tag_name
속성 유형 필수 여부 설명
id 정수/문자열 인증된 사용자가 소유한 프로젝트의 ID 또는 URL 인코딩된 경로입니다.
repository_id 정수 레지스트리 리포지터리의 ID입니다.
tag_name 문자열 태그의 이름입니다.
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags/v10.0.0"

이 작업은 블롭을 삭제하지 않습니다. 디스크 공간을 재활용하려면 Garbage Collection 실행하십시오.

대량 레지스트리 리포지터리 태그 삭제

주어진 기준에 따라 대량으로 레지스트리 리포지터리 태그를 삭제합니다.

개요는 컨테이너 레지스트리 API를 사용하여 *을 제외한 모든 태그 삭제를 참조하세요.

DELETE /projects/:id/registry/repositories/:repository_id/tags
속성 유형 필수 여부 설명
id 정수/문자열 인증된 사용자가 소유한 프로젝트의 ID 또는 URL 인코딩 경로
repository_id 정수 레지스트리 리포지터리의 ID
name_regex 문자열 아니오 삭제할 이름의 re2 정규식입니다. 모든 태그를 삭제하려면 .*을 지정하세요. 참고: name_regexname_regex_delete로 대체되었습니다. 이 필드는 유효성이 검사됩니다.
name_regex_delete 문자열 삭제할 이름의 re2 정규식입니다. 모든 태그를 삭제하려면 .*을 지정하세요. 이 필드는 유효성이 검사됩니다.
name_regex_keep 문자열 아니오 유지할 이름의 re2 정규식입니다. 이 값은 name_regex_delete의 일치 항목을 재정의합니다. 참고: .*로 설정하면 작업이 수행되지 않습니다.
keep_n 정수 아니오 유지할 특정 이름의 최신 태그 수입니다.
older_than 문자열 아니오 인간이 읽을 수 있는 형식의 시간으로 표시된 주어진 시간보다 오래된 태그를 삭제합니다. 1h, 1d, 1month와 같이 표기합니다.

이 API는 성공 시 HTTP 응답 상태 코드 202를 반환하며 다음 작업을 수행합니다:

  • 생성 날짜순으로 모든 태그를 정렬합니다. 생성 날짜는 매니페스트 작성 시간이며 태그 푸시 시간이 아닙니다.
  • 주어진 name_regex_delete (또는 deprecated된 name_regex)와 일치하는 태그만 제거하고 name_regex_keep과 일치하는 태그는 유지합니다.
  • latest라는 이름의 태그는 영구히 유지합니다.
  • 지정된 경우 일치하는 최신 태그 N개를 유지합니다 (keep_n이 지정된 경우).
  • 지정된 경우 주어진 시간보다 오래된 태그만 삭제합니다 (older_than이 지정된 경우).
  • 백그라운드에서 비동기 작업을 예약하여 실행합니다.

이러한 작업은 비동기적으로 실행되며 실행에 시간이 소요될 수 있습니다. 주어진 컨테이너 리포지터리에 대해 한 시간에 한 번씩만 실행할 수 있습니다. 이 작업은 블롭을 삭제하지 않습니다. 디스크 공간을 회수하려면 가비지 수집을 실행하세요.

caution
이 API에 의해 삭제된 태그 수는 GitLab.com의 규모로 인해 제한됩니다. 컨테이너 레지스트리에 많은 태그가 있는 경우 일부만 삭제되므로 이 API를 여러 번 호출해야 할 수 있습니다. 태그를 자동으로 삭제하려면 정리 정책을 사용하세요.

예시:

  • 정규식(40자 Git SHA)과 일치하는 태그 이름을 삭제하고 항상 최소 5개를 유지하며 2일보다 오래된 것은 삭제합니다.

    curl --request DELETE --data 'name_regex_delete=[0-9a-z]{40}' --data 'keep_n=5' --data 'older_than=2d' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    
  • 모든 태그를 삭제하고 항상 최신 5개를 유지합니다.

    curl --request DELETE --data 'name_regex_delete=.*' --data 'keep_n=5' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    
  • 모든 태그를 삭제하되, stable로 시작하는 태그만 유지합니다.

    curl --request DELETE --data 'name_regex_delete=.*' --data 'name_regex_keep=stable.*' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    
  • 1개월 이전에 만들어진 모든 태그를 삭제합니다.

    curl --request DELETE --data 'name_regex_delete=.*' --data 'older_than=1month' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    

+를 포함하는 정규식과 cURL 사용

cURL을 사용할 때, 정규식에 + 문자는 GitLab Rails 백엔드에서 올바르게 처리되기 위해 URL 인코딩되어야 합니다. 예를 들어:

curl --request DELETE --data-urlencode 'name_regex_delete=dev-.+' \
     --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"

인스턴스 전역 엔드포인트

위에서 설명한 그룹 및 프로젝트별 GitLab API 외에도 컨테이너 레지스트리에는 자체 엔드포인트가 있습니다. 해당 엔드포인트를 조회하려면 인증 토큰을 얻고 사용하는 레지스트리의 내장 메커니즘을 따르세요.

note
이는 GitLab 애플리케이션의 프로젝트 또는 개인 액세스 토큰과는 다릅니다.

GitLab에서 토큰 얻기

GET ${CI_SERVER_URL}/jwt/auth?service=container_registry&scope=*

유효한 토큰을 얻으려면 올바른 스코프 및 작업을 지정해야 합니다:

$ SCOPE="repository:${CI_REGISTRY_IMAGE}:delete" #또는 push, pull

$ curl  --request GET --user "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" \
        "https://gitlab.example.com/jwt/auth?service=container_registry&scope=${SCOPE}"
{"token":" ... "}

참조에 의한 이미지 태그 삭제

caution
Endpoint v2/<name>/tags/reference/<tag>은 GitLab 16.4에서 사용 중지되었으며 17.0에서 삭제될 예정입니다. 대신 v2/<name>/manifests/<tag>을 사용하세요. 이 변경 사항은 파괴적인 변경입니다.
DELETE http(s)://${CI_REGISTRY}/v2/${CI_REGISTRY_IMAGE}/tags/reference/${CI_COMMIT_SHORT_SHA}

미리 정의된 CI_REGISTRY_USERCI_REGISTRY_PASSWORD 변수로 검색된 토큰을 사용하여 GitLab 인스턴스에서 참조에 의해 이미지 태그를 삭제할 수 있습니다. tag_delete 컨테이너 레지스트리 기능을 활성화해야 합니다.

$ curl  --request DELETE --header "Authorization: Bearer <token_from_above>" \
        --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        "https://gitlab.example.com:5050/v2/${CI_REGISTRY_IMAGE}/manifests/${CI_COMMIT_SHORT_SHA}"

모든 컨테이너 리포지터리 나열

GET http(s)://${CI_REGISTRY}/v2/_catalog

GitLab 인스턴스에 모든 컨테이너 리포지터리를 나열하려면 관리자 자격 증명이 필요합니다:

$ SCOPE="registry:catalog:*"

$ curl  --request GET --user "<admin-username>:<admin-password>" \
        "https://gitlab.example.com/jwt/auth?service=container_registry&scope=${SCOPE}"
{"token":" ... "}

$ curl --header "Authorization: Bearer <token_from_above>" https://gitlab.example.com:5050/v2/_catalog