InfoGrab Docs

패키지 레지스트리의 PyPI 패키지

요약

Python 패키지 인덱스(PyPI)는 Python의 공식 서드파티 소프트웨어 저장소입니다. 패키지 레지스트리는 다음과 함께 작동합니다: pip 및 twine 클라이언트가 사용하는 특정 API 엔드포인트 문서는 PyPI API 문서를 참조하세요.

Python 패키지 인덱스(PyPI)는 Python의 공식 서드파티 소프트웨어 저장소입니다. GitLab PyPI 패키지 레지스트리를 사용하여 GitLab 프로젝트, 그룹 및 조직에서 Python 패키지를 게시하고 공유할 수 있습니다. 이 통합을 통해 코드와 함께 Python 종속성을 관리하여 GitLab 내에서 Python 개발을 위한 원활한 워크플로를 제공합니다.

패키지 레지스트리는 다음과 함께 작동합니다:

piptwine 클라이언트가 사용하는 특정 API 엔드포인트 문서는 PyPI API 문서를 참조하세요.

PyPI 패키지를 빌드하는 방법을 알아보세요.

패키지 요청 전달 보안 공지#

GitLab PyPI 패키지 레지스트리를 사용할 때, GitLab 레지스트리에서 찾을 수 없는 패키지 요청은 자동으로 pypi.org로 전달됩니다. 이 동작으로 인해 --index-url 플래그를 사용하더라도 pypi.org에서 패키지가 다운로드될 수 있습니다.

비공개 패키지 작업 시 최대 보안을 위해:

  • 그룹 설정에서 패키지 전달을 끕니다.
  • 패키지를 설치할 때 --index-url--no-index 플래그를 모두 사용합니다.

사전 요구 사항:

  • 그룹에 대한 Owner 권한이 있어야 합니다.

패키지 요청 전달을 끄려면:

  1. 상단 바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Settings > Packages and registries를 선택합니다.
  3. Package forwarding 아래에서 Forward PyPI package requests 체크박스를 지웁니다.

Admin 영역에서 패키지 전달을 끄는 방법은 패키지 전달 제어를 참조하세요.

GitLab 패키지 레지스트리로 인증#

GitLab 패키지 레지스트리와 상호 작용하기 전에 인증해야 합니다.

다음으로 인증할 수 있습니다:

여기에 문서화된 방법 이외의 인증 방법을 사용하지 마세요. 문서화되지 않은 인증 방법은 나중에 제거될 수 있습니다.

GitLab 토큰으로 인증하려면:

  • TWINE_USERNAMETWINE_PASSWORD 환경 변수를 업데이트합니다.

예를 들면:

run:
  image: python:latest
  variables:
    TWINE_USERNAME: <personal_access_token_name>
    TWINE_PASSWORD: <personal_access_token>
  script:
    - pip install build twine
    - python -m build
    - python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
run:
  image: python:latest
  variables:
    TWINE_USERNAME: <deploy_token_username>
    TWINE_PASSWORD: <deploy_token>
  script:
    - pip install build twine
    - python -m build
    - python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
run:
  image: python:latest
  variables:
    TWINE_USERNAME: gitlab-ci-token
    TWINE_PASSWORD: $CI_JOB_TOKEN
  script:
    - pip install build twine
    - python -m build
    - python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*

그룹에 대한 인증#

그룹의 패키지 레지스트리로 인증하려면:

  • 패키지 레지스트리로 인증하되, 프로젝트 URL 대신 그룹 URL을 사용합니다:
https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi

PyPI 패키지 게시#

twine으로 패키지를 게시할 수 있습니다.

사전 요구 사항:

PyPI 패키지는 프로젝트 ID를 사용하여 게시됩니다. 프로젝트가 그룹에 있는 경우, 프로젝트 레지스트리에 게시된 PyPI 패키지는 그룹 레지스트리에서도 사용할 수 있습니다. 자세한 내용은 그룹에서 설치를 참조하세요.

패키지를 게시하려면:

  1. 리포지터리 소스를 정의하고 ~/.pypirc 파일을 편집하여 다음을 추가합니다:

    [distutils]
    index-servers =
        gitlab
    
    [gitlab]
    repository = https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi
    
  2. twine으로 패키지를 업로드합니다:

    python3 -m twine upload --repository gitlab dist/*
    

    패키지가 성공적으로 게시되면 다음과 같은 메시지가 표시됩니다:

    Uploading distributions to https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi
    Uploading mypypipackage-0.0.1-py3-none-any.whl
    100%|███████████████████████████████████████████████████████████████████████████████████████████| 4.58k/4.58k [00:00<00:00, 10.9kB/s]
    Uploading mypypipackage-0.0.1.tar.gz
    100%|███████████████████████████████████████████████████████████████████████████████████████████| 4.24k/4.24k [00:00<00:00, 11.0kB/s]
    

패키지가 패키지 레지스트리에 게시되고 Packages and registries 페이지에 표시됩니다.

인라인 인증으로 게시#

리포지터리 소스를 정의하기 위해 .pypirc 파일을 사용하지 않은 경우, 인라인 인증으로 리포지터리에 게시할 수 있습니다:

TWINE_PASSWORD=<personal_access_token, deploy_token, or $CI_JOB_TOKEN> \
TWINE_USERNAME=<username, deploy_token_username, or gitlab-ci-token> \
python3 -m twine upload --repository-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi dist/*

동일한 이름과 버전의 패키지 게시#

동일한 이름과 버전의 패키지가 이미 있는 경우 패키지를 게시할 수 없습니다. 먼저 기존 패키지를 삭제해야 합니다. 동일한 패키지를 두 번 이상 게시하려고 하면 400 Bad Request 오류가 발생합니다.

PyPI 패키지 설치#

기본적으로 GitLab 패키지 레지스트리에서 PyPI 패키지를 찾을 수 없는 경우, 요청은 pypi.org로 전달됩니다. 요청 전달을 방지하는 방법에 대한 자세한 내용은 패키지 요청 전달 및 보안 공지를 참조하세요.

이 동작:

  • 모든 GitLab 인스턴스에 대해 기본적으로 활성화됩니다.
  • 그룹의 Packages and registries 설정에서 구성할 수 있습니다.
  • --index-url 플래그를 사용할 때도 적용됩니다.

관리자는 Continuous Integration 설정에서 이 동작을 전역으로 비활성화할 수 있습니다. 그룹 Owner는 그룹 설정의 Packages and registries 섹션에서 특정 그룹에 대해 이 동작을 비활성화할 수 있습니다.

Note

--index-url 옵션을 사용할 때 기본 포트인 경우 포트를 지정하지 마세요. http URL은 기본값이 80이고 https URL은 기본값이 443입니다.

프로젝트에서 설치#

패키지의 최신 버전을 설치하려면 다음 명령을 사용합니다:

pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple --no-deps <package_name>
  • <package_name>은 패키지 이름입니다.
  • <personal_access_token_name>read_api 범위의 개인 액세스 토큰 이름입니다.
  • <personal_access_token>read_api 범위의 개인 액세스 토큰입니다.
  • <project_id>는 프로젝트의 URL 인코딩된 경로(예: group%2Fproject) 또는 프로젝트 ID(예: 42)입니다.

이 명령들에서 --index-url 대신 --extra-index-url을 사용할 수 있습니다. 가이드를 따르고 MyPyPiPackage 패키지를 설치하려는 경우 다음을 실행할 수 있습니다:

pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple

이 메시지는 패키지가 성공적으로 설치되었음을 나타냅니다:

Looking in indexes: https://<personal_access_token_name>:****@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
Collecting mypypipackage
  Downloading https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/files/d53334205552a355fee8ca35a164512ef7334f33d309e60240d57073ee4386e6/mypypipackage-0.0.1-py3-none-any.whl (1.6 kB)
Installing collected packages: mypypipackage
Successfully installed mypypipackage-0.0.1

그룹에서 설치#

그룹에서 패키지의 최신 버전을 설치하려면 다음 명령을 사용합니다:

pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple --no-deps <package_name>

이 명령에서:

  • <package_name>은 패키지 이름입니다.
  • <personal_access_token_name>read_api 범위의 개인 액세스 토큰 이름입니다.
  • <personal_access_token>read_api 범위의 개인 액세스 토큰입니다.
  • <group_id>는 그룹 ID입니다.

이 명령들에서 --index-url 대신 --extra-index-url을 사용할 수 있습니다. 가이드를 따르고 MyPyPiPackage 패키지를 설치하려는 경우 다음을 실행할 수 있습니다:

pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple

패키지 이름#

GitLab은 Python 정규화 이름(PEP-503)을 사용하는 패키지를 찾습니다. 문자 -, _, .은 모두 동일하게 취급되고 반복 문자는 제거됩니다.

my.package에 대한 pip install 요청은 my-package, my_package, my....package와 같이 세 문자 중 하나와 일치하는 패키지를 찾습니다.

보안 영향#

PyPI 패키지를 설치할 때 --extra-index-url--index-url을 사용할 때의 보안 영향은 중요하며 자세히 이해할 가치가 있습니다:

  • --index-url: 이 옵션은 기본 PyPI 인덱스 URL을 지정된 URL로 대체합니다. 기본적으로 켜져 있는 GitLab 패키지 전달 설정은 패키지 레지스트리에 없는 패키지를 PyPI에서 여전히 다운로드할 수 있습니다. GitLab에서만 패키지가 설치되도록 하려면:
    • 그룹 설정에서 패키지 전달을 비활성화합니다.
    • --index-url--no-index 플래그를 함께 사용합니다.
  • --extra-index-url: 이 옵션은 기본 PyPI 인덱스와 함께 검색할 추가 인덱스를 추가합니다. 기본 PyPI와 추가 인덱스 모두에서 패키지를 확인하므로 덜 안전하고 의존성 혼동 공격에 더 취약합니다.

비공개 패키지를 사용할 때 다음 모범 사례를 고려하세요:

  • 그룹의 패키지 전달 설정을 확인합니다.
  • 비공개 패키지를 설치할 때 --no-index--index-url 플래그를 함께 사용합니다.
  • pip debug를 사용하여 패키지 소스를 정기적으로 감사합니다.

PyPI 패키지 삭제#

사전 요구 사항:

  • Maintainer 또는 Owner 권한이 있어야 합니다.

패키지를 삭제하기 전에 관련 보안 위험을 이해해야 합니다.

패키지를 삭제하려면 다음 중 하나를 사용합니다:

CI/CD 파이프라인에서 비공개 PyPI 패키지 설치#

CI/CD Job 토큰을 사용하여 CI/CD 파이프라인에서 비공개 PyPI 패키지를 설치할 수 있습니다. Job 토큰은 자동으로 인증되며 동일한 최상위 그룹 내의 다른 프로젝트의 패키지에도 액세스할 수 있습니다.

사전 요구 사항:

  • 패키지가 다른 프로젝트에 있는 경우, 해당 프로젝트는 프로젝트의 Job 토큰을 허용해야 합니다. 자세한 내용은 Job 토큰 액세스 제어를 참조하세요.
  • CI/CD Job 토큰으로 인증할 때 사용자 이름은 gitlab-ci-token이어야 합니다.

인라인 자격 증명 사용#

pip install 명령에 직접 CI_JOB_TOKEN을 전달합니다:

install:
  image: python:latest
  script:
    - pip install <package_name> --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple

그룹의 모든 프로젝트에서 패키지를 포함하는 그룹 인덱스에서 설치하려면:

install:
  image: python:latest
  script:
    - pip install <package_name> --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple

CI/CD에서 .netrc 파일 사용#

.netrcrequirements.txt를 자격 증명 없이 유지하므로 동일한 파일이 로컬과 CI/CD 파이프라인 모두에서 작동합니다. pip는 .netrc 파일을 자동으로 읽어 주어진 호스트 이름의 자격 증명을 찾습니다. 자세한 내용은 .netrc 지원을 참조하세요.

.gitlab-ci.yml에서 before_script.netrc 파일을 만듭니다:

install:
  image: python:latest
  before_script:
    - |
      echo "machine gitlab.example.com
      login gitlab-ci-token
      password ${CI_JOB_TOKEN}" > ~/.netrc
  script:
    - pip install -r requirements.txt

requirements.txt는 자격 증명 없이 GitLab 레지스트리를 참조합니다:

--extra-index-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
package-name==1.0.0

로컬 개발의 경우, api 범위의 개인 액세스 토큰을 사용하는 ~/.netrc 파일을 만듭니다:

machine gitlab.example.com
login <personal_access_token_name>
password <personal_access_token>
Note

.netrc 파일은 호스트 이름당 하나의 자격 증명 세트를 구성합니다. 여러 GitLab 인스턴스에서 패키지로 인증해야 하는 경우 각 호스트 이름에 대해 별도의 machine 항목을 추가합니다.

Docker 빌드 중 비공개 패키지 설치#

비공개 PyPI 패키지가 필요한 Docker 이미지를 빌드할 때 빌드 인수로 CI_JOB_TOKEN을 전달합니다:

build:
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN -t my-image .

Dockerfile에서 토큰을 사용하여 레지스트리로 인증합니다:

ARG CI_JOB_TOKEN
RUN pip install <package_name> --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
Note

빌드 인수는 이미지 히스토리에 표시될 수 있습니다. 프로덕션 이미지의 경우, 토큰이 최종 이미지 레이어에 없도록 멀티 스테이지 빌드를 사용합니다.

requirements.txt 사용#

pip가 공개 레지스트리에 액세스하도록 하려면 requirements.txt 파일에 --extra-index-url 파라미터와 레지스트리 URL을 추가합니다.

--extra-index-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
package-name==1.0.0

이것이 비공개 레지스트리인 경우 몇 가지 방법으로 인증할 수 있습니다. 예를 들면:

  • 개인 액세스 토큰을 사용하는 requirements.txt 파일:

    --extra-index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
    package-name==1.0.0
    
  • 개인 액세스 토큰을 사용하는 ~/.netrc 파일:

    machine gitlab.example.com
    login <personal_access_token_name>
    password <personal_access_token>
    

PyPI 패키지 버전 관리#

적절한 버전 관리는 PyPI 패키지를 효과적으로 관리하는 데 중요합니다. 패키지가 올바르게 버전 관리되도록 다음 모범 사례를 따르세요.

시맨틱 버전 관리(SemVer) 사용#

패키지에 시맨틱 버전 관리를 채택합니다. 버전 번호는 MAJOR.MINOR.PATCH 형식이어야 합니다:

  • 호환되지 않는 API 변경의 경우 MAJOR 버전을 증가시킵니다.
  • 하위 호환 가능한 새 기능의 경우 MINOR 버전을 증가시킵니다.
  • 하위 호환 가능한 버그 수정의 경우 PATCH 버전을 증가시킵니다.

예: 1.0.0, 1.1.0, 1.1.1.

새 프로젝트는 버전 0.1.0으로 시작하세요. 이는 API가 아직 안정적이지 않은 초기 개발 단계를 나타냅니다.

유효한 버전 문자열 사용#

버전 문자열이 PyPI 표준에 따라 유효한지 확인합니다. GitLab은 버전 문자열을 검증하기 위해 특정 정규식을 사용합니다:

\A(?:
    v?
    (?:([0-9]+)!)?                                                 (?# epoch)
    ([0-9]+(?:\.[0-9]+)*)                                          (?# release segment)
    ([-_\.]?((a|b|c|rc|alpha|beta|pre|preview))[-_\.]?([0-9]+)?)?  (?# pre-release)
    ((?:-([0-9]+))|(?:[-_\.]?(post|rev|r)[-_\.]?([0-9]+)?))?       (?# post release)
    ([-_\.]?(dev)[-_\.]?([0-9]+)?)?                                (?# dev release)
    (?:\+([a-z0-9]+(?:[-_\.][a-z0-9]+)*))?                         (?# local version)
)\z}xi

정규식 편집기를 사용하여 정규식을 실험하고 버전 문자열을 테스트할 수 있습니다.

정규식에 대한 자세한 내용은 Python 문서를 참조하세요.

지원되는 CLI 명령#

GitLab PyPI 리포지터리는 다음 CLI 명령을 지원합니다:

  • twine upload: 레지스트리에 패키지를 업로드합니다.
  • pip install: 레지스트리에서 PyPI 패키지를 설치합니다.

문제 해결#

성능을 향상시키기 위해 pip 명령은 패키지와 관련된 파일을 캐시합니다. pip는 데이터를 자체적으로 제거하지 않습니다. 새 패키지가 설치될수록 캐시가 커집니다. 문제가 발생하면 다음 명령으로 캐시를 지웁니다:

pip cache purge

여러 index-url 또는 extra-index-url 파라미터#

여러 index-urlextra-index-url 파라미터를 정의할 수 있습니다.

다른 인증 토큰으로 동일한 도메인 이름(예: gitlab.example.com)을 여러 번 사용하면 pip가 패키지를 찾지 못할 수 있습니다. 이 문제는 명령 실행 중 pip토큰을 등록하고 저장하는 방식 때문입니다.

이 문제를 해결하려면 index-urlextra-index-url 값이 대상으로 하는 모든 프로젝트나 그룹의 공통 상위 그룹에서 read_package_registry 범위의 그룹 배포 토큰을 사용할 수 있습니다.

예상치 못한 패키지 소스#

GitLab 레지스트리만 사용하려 했을 때 PyPI에서 패키지가 설치되는 경우:

  • 그룹의 패키지 전달 설정을 확인합니다.
  • PyPI 폴백을 방지하기 위해 --no-index--index-url 플래그를 함께 사용합니다.
  • pip debug를 사용하여 패키지 소스를 정기적으로 감사합니다.

패키지 레지스트리의 PyPI 패키지

Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

Python 패키지 인덱스(PyPI)는 Python의 공식 서드파티 소프트웨어 저장소입니다. 패키지 레지스트리는 다음과 함께 작동합니다: pip 및 twine 클라이언트가 사용하는 특정 API 엔드포인트 문서는 PyPI API 문서를 참조하세요.

Python 패키지 인덱스(PyPI)는 Python의 공식 서드파티 소프트웨어 저장소입니다. GitLab PyPI 패키지 레지스트리를 사용하여 GitLab 프로젝트, 그룹 및 조직에서 Python 패키지를 게시하고 공유할 수 있습니다. 이 통합을 통해 코드와 함께 Python 종속성을 관리하여 GitLab 내에서 Python 개발을 위한 원활한 워크플로를 제공합니다.

패키지 레지스트리는 다음과 함께 작동합니다:

piptwine 클라이언트가 사용하는 특정 API 엔드포인트 문서는 PyPI API 문서를 참조하세요.

PyPI 패키지를 빌드하는 방법을 알아보세요.

패키지 요청 전달 보안 공지#

GitLab PyPI 패키지 레지스트리를 사용할 때, GitLab 레지스트리에서 찾을 수 없는 패키지 요청은 자동으로 pypi.org로 전달됩니다. 이 동작으로 인해 --index-url 플래그를 사용하더라도 pypi.org에서 패키지가 다운로드될 수 있습니다.

비공개 패키지 작업 시 최대 보안을 위해:

  • 그룹 설정에서 패키지 전달을 끕니다.
  • 패키지를 설치할 때 --index-url--no-index 플래그를 모두 사용합니다.

사전 요구 사항:

  • 그룹에 대한 Owner 권한이 있어야 합니다.

패키지 요청 전달을 끄려면:

  1. 상단 바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Settings > Packages and registries를 선택합니다.
  3. Package forwarding 아래에서 Forward PyPI package requests 체크박스를 지웁니다.

Admin 영역에서 패키지 전달을 끄는 방법은 패키지 전달 제어를 참조하세요.

GitLab 패키지 레지스트리로 인증#

GitLab 패키지 레지스트리와 상호 작용하기 전에 인증해야 합니다.

다음으로 인증할 수 있습니다:

여기에 문서화된 방법 이외의 인증 방법을 사용하지 마세요. 문서화되지 않은 인증 방법은 나중에 제거될 수 있습니다.

GitLab 토큰으로 인증하려면:

  • TWINE_USERNAMETWINE_PASSWORD 환경 변수를 업데이트합니다.

예를 들면:

run:
  image: python:latest
  variables:
    TWINE_USERNAME: <personal_access_token_name>
    TWINE_PASSWORD: <personal_access_token>
  script:
    - pip install build twine
    - python -m build
    - python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
run:
  image: python:latest
  variables:
    TWINE_USERNAME: <deploy_token_username>
    TWINE_PASSWORD: <deploy_token>
  script:
    - pip install build twine
    - python -m build
    - python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
run:
  image: python:latest
  variables:
    TWINE_USERNAME: gitlab-ci-token
    TWINE_PASSWORD: $CI_JOB_TOKEN
  script:
    - pip install build twine
    - python -m build
    - python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*

그룹에 대한 인증#

그룹의 패키지 레지스트리로 인증하려면:

  • 패키지 레지스트리로 인증하되, 프로젝트 URL 대신 그룹 URL을 사용합니다:
https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi

PyPI 패키지 게시#

twine으로 패키지를 게시할 수 있습니다.

사전 요구 사항:

PyPI 패키지는 프로젝트 ID를 사용하여 게시됩니다. 프로젝트가 그룹에 있는 경우, 프로젝트 레지스트리에 게시된 PyPI 패키지는 그룹 레지스트리에서도 사용할 수 있습니다. 자세한 내용은 그룹에서 설치를 참조하세요.

패키지를 게시하려면:

  1. 리포지터리 소스를 정의하고 ~/.pypirc 파일을 편집하여 다음을 추가합니다:

    [distutils]
    index-servers =
        gitlab
    
    [gitlab]
    repository = https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi
    
  2. twine으로 패키지를 업로드합니다:

    python3 -m twine upload --repository gitlab dist/*
    

    패키지가 성공적으로 게시되면 다음과 같은 메시지가 표시됩니다:

    Uploading distributions to https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi
    Uploading mypypipackage-0.0.1-py3-none-any.whl
    100%|███████████████████████████████████████████████████████████████████████████████████████████| 4.58k/4.58k [00:00<00:00, 10.9kB/s]
    Uploading mypypipackage-0.0.1.tar.gz
    100%|███████████████████████████████████████████████████████████████████████████████████████████| 4.24k/4.24k [00:00<00:00, 11.0kB/s]
    

패키지가 패키지 레지스트리에 게시되고 Packages and registries 페이지에 표시됩니다.

인라인 인증으로 게시#

리포지터리 소스를 정의하기 위해 .pypirc 파일을 사용하지 않은 경우, 인라인 인증으로 리포지터리에 게시할 수 있습니다:

TWINE_PASSWORD=<personal_access_token, deploy_token, or $CI_JOB_TOKEN> \
TWINE_USERNAME=<username, deploy_token_username, or gitlab-ci-token> \
python3 -m twine upload --repository-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi dist/*

동일한 이름과 버전의 패키지 게시#

동일한 이름과 버전의 패키지가 이미 있는 경우 패키지를 게시할 수 없습니다. 먼저 기존 패키지를 삭제해야 합니다. 동일한 패키지를 두 번 이상 게시하려고 하면 400 Bad Request 오류가 발생합니다.

PyPI 패키지 설치#

기본적으로 GitLab 패키지 레지스트리에서 PyPI 패키지를 찾을 수 없는 경우, 요청은 pypi.org로 전달됩니다. 요청 전달을 방지하는 방법에 대한 자세한 내용은 패키지 요청 전달 및 보안 공지를 참조하세요.

이 동작:

  • 모든 GitLab 인스턴스에 대해 기본적으로 활성화됩니다.
  • 그룹의 Packages and registries 설정에서 구성할 수 있습니다.
  • --index-url 플래그를 사용할 때도 적용됩니다.

관리자는 Continuous Integration 설정에서 이 동작을 전역으로 비활성화할 수 있습니다. 그룹 Owner는 그룹 설정의 Packages and registries 섹션에서 특정 그룹에 대해 이 동작을 비활성화할 수 있습니다.

Note

--index-url 옵션을 사용할 때 기본 포트인 경우 포트를 지정하지 마세요. http URL은 기본값이 80이고 https URL은 기본값이 443입니다.

프로젝트에서 설치#

패키지의 최신 버전을 설치하려면 다음 명령을 사용합니다:

pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple --no-deps <package_name>
  • <package_name>은 패키지 이름입니다.
  • <personal_access_token_name>read_api 범위의 개인 액세스 토큰 이름입니다.
  • <personal_access_token>read_api 범위의 개인 액세스 토큰입니다.
  • <project_id>는 프로젝트의 URL 인코딩된 경로(예: group%2Fproject) 또는 프로젝트 ID(예: 42)입니다.

이 명령들에서 --index-url 대신 --extra-index-url을 사용할 수 있습니다. 가이드를 따르고 MyPyPiPackage 패키지를 설치하려는 경우 다음을 실행할 수 있습니다:

pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple

이 메시지는 패키지가 성공적으로 설치되었음을 나타냅니다:

Looking in indexes: https://<personal_access_token_name>:****@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
Collecting mypypipackage
  Downloading https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/files/d53334205552a355fee8ca35a164512ef7334f33d309e60240d57073ee4386e6/mypypipackage-0.0.1-py3-none-any.whl (1.6 kB)
Installing collected packages: mypypipackage
Successfully installed mypypipackage-0.0.1

그룹에서 설치#

그룹에서 패키지의 최신 버전을 설치하려면 다음 명령을 사용합니다:

pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple --no-deps <package_name>

이 명령에서:

  • <package_name>은 패키지 이름입니다.
  • <personal_access_token_name>read_api 범위의 개인 액세스 토큰 이름입니다.
  • <personal_access_token>read_api 범위의 개인 액세스 토큰입니다.
  • <group_id>는 그룹 ID입니다.

이 명령들에서 --index-url 대신 --extra-index-url을 사용할 수 있습니다. 가이드를 따르고 MyPyPiPackage 패키지를 설치하려는 경우 다음을 실행할 수 있습니다:

pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple

패키지 이름#

GitLab은 Python 정규화 이름(PEP-503)을 사용하는 패키지를 찾습니다. 문자 -, _, .은 모두 동일하게 취급되고 반복 문자는 제거됩니다.

my.package에 대한 pip install 요청은 my-package, my_package, my....package와 같이 세 문자 중 하나와 일치하는 패키지를 찾습니다.

보안 영향#

PyPI 패키지를 설치할 때 --extra-index-url--index-url을 사용할 때의 보안 영향은 중요하며 자세히 이해할 가치가 있습니다:

  • --index-url: 이 옵션은 기본 PyPI 인덱스 URL을 지정된 URL로 대체합니다. 기본적으로 켜져 있는 GitLab 패키지 전달 설정은 패키지 레지스트리에 없는 패키지를 PyPI에서 여전히 다운로드할 수 있습니다. GitLab에서만 패키지가 설치되도록 하려면:
    • 그룹 설정에서 패키지 전달을 비활성화합니다.
    • --index-url--no-index 플래그를 함께 사용합니다.
  • --extra-index-url: 이 옵션은 기본 PyPI 인덱스와 함께 검색할 추가 인덱스를 추가합니다. 기본 PyPI와 추가 인덱스 모두에서 패키지를 확인하므로 덜 안전하고 의존성 혼동 공격에 더 취약합니다.

비공개 패키지를 사용할 때 다음 모범 사례를 고려하세요:

  • 그룹의 패키지 전달 설정을 확인합니다.
  • 비공개 패키지를 설치할 때 --no-index--index-url 플래그를 함께 사용합니다.
  • pip debug를 사용하여 패키지 소스를 정기적으로 감사합니다.

PyPI 패키지 삭제#

사전 요구 사항:

  • Maintainer 또는 Owner 권한이 있어야 합니다.

패키지를 삭제하기 전에 관련 보안 위험을 이해해야 합니다.

패키지를 삭제하려면 다음 중 하나를 사용합니다:

CI/CD 파이프라인에서 비공개 PyPI 패키지 설치#

CI/CD Job 토큰을 사용하여 CI/CD 파이프라인에서 비공개 PyPI 패키지를 설치할 수 있습니다. Job 토큰은 자동으로 인증되며 동일한 최상위 그룹 내의 다른 프로젝트의 패키지에도 액세스할 수 있습니다.

사전 요구 사항:

  • 패키지가 다른 프로젝트에 있는 경우, 해당 프로젝트는 프로젝트의 Job 토큰을 허용해야 합니다. 자세한 내용은 Job 토큰 액세스 제어를 참조하세요.
  • CI/CD Job 토큰으로 인증할 때 사용자 이름은 gitlab-ci-token이어야 합니다.

인라인 자격 증명 사용#

pip install 명령에 직접 CI_JOB_TOKEN을 전달합니다:

install:
  image: python:latest
  script:
    - pip install <package_name> --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple

그룹의 모든 프로젝트에서 패키지를 포함하는 그룹 인덱스에서 설치하려면:

install:
  image: python:latest
  script:
    - pip install <package_name> --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple

CI/CD에서 .netrc 파일 사용#

.netrcrequirements.txt를 자격 증명 없이 유지하므로 동일한 파일이 로컬과 CI/CD 파이프라인 모두에서 작동합니다. pip는 .netrc 파일을 자동으로 읽어 주어진 호스트 이름의 자격 증명을 찾습니다. 자세한 내용은 .netrc 지원을 참조하세요.

.gitlab-ci.yml에서 before_script.netrc 파일을 만듭니다:

install:
  image: python:latest
  before_script:
    - |
      echo "machine gitlab.example.com
      login gitlab-ci-token
      password ${CI_JOB_TOKEN}" > ~/.netrc
  script:
    - pip install -r requirements.txt

requirements.txt는 자격 증명 없이 GitLab 레지스트리를 참조합니다:

--extra-index-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
package-name==1.0.0

로컬 개발의 경우, api 범위의 개인 액세스 토큰을 사용하는 ~/.netrc 파일을 만듭니다:

machine gitlab.example.com
login <personal_access_token_name>
password <personal_access_token>
Note

.netrc 파일은 호스트 이름당 하나의 자격 증명 세트를 구성합니다. 여러 GitLab 인스턴스에서 패키지로 인증해야 하는 경우 각 호스트 이름에 대해 별도의 machine 항목을 추가합니다.

Docker 빌드 중 비공개 패키지 설치#

비공개 PyPI 패키지가 필요한 Docker 이미지를 빌드할 때 빌드 인수로 CI_JOB_TOKEN을 전달합니다:

build:
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN -t my-image .

Dockerfile에서 토큰을 사용하여 레지스트리로 인증합니다:

ARG CI_JOB_TOKEN
RUN pip install <package_name> --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
Note

빌드 인수는 이미지 히스토리에 표시될 수 있습니다. 프로덕션 이미지의 경우, 토큰이 최종 이미지 레이어에 없도록 멀티 스테이지 빌드를 사용합니다.

requirements.txt 사용#

pip가 공개 레지스트리에 액세스하도록 하려면 requirements.txt 파일에 --extra-index-url 파라미터와 레지스트리 URL을 추가합니다.

--extra-index-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
package-name==1.0.0

이것이 비공개 레지스트리인 경우 몇 가지 방법으로 인증할 수 있습니다. 예를 들면:

  • 개인 액세스 토큰을 사용하는 requirements.txt 파일:

    --extra-index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
    package-name==1.0.0
    
  • 개인 액세스 토큰을 사용하는 ~/.netrc 파일:

    machine gitlab.example.com
    login <personal_access_token_name>
    password <personal_access_token>
    

PyPI 패키지 버전 관리#

적절한 버전 관리는 PyPI 패키지를 효과적으로 관리하는 데 중요합니다. 패키지가 올바르게 버전 관리되도록 다음 모범 사례를 따르세요.

시맨틱 버전 관리(SemVer) 사용#

패키지에 시맨틱 버전 관리를 채택합니다. 버전 번호는 MAJOR.MINOR.PATCH 형식이어야 합니다:

  • 호환되지 않는 API 변경의 경우 MAJOR 버전을 증가시킵니다.
  • 하위 호환 가능한 새 기능의 경우 MINOR 버전을 증가시킵니다.
  • 하위 호환 가능한 버그 수정의 경우 PATCH 버전을 증가시킵니다.

예: 1.0.0, 1.1.0, 1.1.1.

새 프로젝트는 버전 0.1.0으로 시작하세요. 이는 API가 아직 안정적이지 않은 초기 개발 단계를 나타냅니다.

유효한 버전 문자열 사용#

버전 문자열이 PyPI 표준에 따라 유효한지 확인합니다. GitLab은 버전 문자열을 검증하기 위해 특정 정규식을 사용합니다:

\A(?:
    v?
    (?:([0-9]+)!)?                                                 (?# epoch)
    ([0-9]+(?:\.[0-9]+)*)                                          (?# release segment)
    ([-_\.]?((a|b|c|rc|alpha|beta|pre|preview))[-_\.]?([0-9]+)?)?  (?# pre-release)
    ((?:-([0-9]+))|(?:[-_\.]?(post|rev|r)[-_\.]?([0-9]+)?))?       (?# post release)
    ([-_\.]?(dev)[-_\.]?([0-9]+)?)?                                (?# dev release)
    (?:\+([a-z0-9]+(?:[-_\.][a-z0-9]+)*))?                         (?# local version)
)\z}xi

정규식 편집기를 사용하여 정규식을 실험하고 버전 문자열을 테스트할 수 있습니다.

정규식에 대한 자세한 내용은 Python 문서를 참조하세요.

지원되는 CLI 명령#

GitLab PyPI 리포지터리는 다음 CLI 명령을 지원합니다:

  • twine upload: 레지스트리에 패키지를 업로드합니다.
  • pip install: 레지스트리에서 PyPI 패키지를 설치합니다.

문제 해결#

성능을 향상시키기 위해 pip 명령은 패키지와 관련된 파일을 캐시합니다. pip는 데이터를 자체적으로 제거하지 않습니다. 새 패키지가 설치될수록 캐시가 커집니다. 문제가 발생하면 다음 명령으로 캐시를 지웁니다:

pip cache purge

여러 index-url 또는 extra-index-url 파라미터#

여러 index-urlextra-index-url 파라미터를 정의할 수 있습니다.

다른 인증 토큰으로 동일한 도메인 이름(예: gitlab.example.com)을 여러 번 사용하면 pip가 패키지를 찾지 못할 수 있습니다. 이 문제는 명령 실행 중 pip토큰을 등록하고 저장하는 방식 때문입니다.

이 문제를 해결하려면 index-urlextra-index-url 값이 대상으로 하는 모든 프로젝트나 그룹의 공통 상위 그룹에서 read_package_registry 범위의 그룹 배포 토큰을 사용할 수 있습니다.

예상치 못한 패키지 소스#

GitLab 레지스트리만 사용하려 했을 때 PyPI에서 패키지가 설치되는 경우:

  • 그룹의 패키지 전달 설정을 확인합니다.
  • PyPI 폴백을 방지하기 위해 --no-index--index-url 플래그를 함께 사용합니다.
  • pip debug를 사용하여 패키지 소스를 정기적으로 감사합니다.