InfoGrab Docs

CI/CD 캐싱 예시

요약

캐싱을 사용하면 작업이 실행될 때마다 종속성과 빌드 아티팩트를 다운로드하지 않아도 됩니다. 더 많은 예시는 GitLab CI/CD 템플릿을 참조하세요. 이 예시들은 작업 및 브랜치 간에 캐시를 공유하는 다양한 접근 방법을 보여줍니다.

캐싱을 사용하면 작업이 실행될 때마다 종속성과 빌드 아티팩트를 다운로드하지 않아도 됩니다. 캐싱은 이전에 다운로드한 콘텐츠를 재사용하여 CI/CD 파이프라인 속도를 높입니다.

더 많은 예시는 GitLab CI/CD 템플릿을 참조하세요.

캐시 전략#

이 예시들은 작업 및 브랜치 간에 캐시를 공유하는 다양한 접근 방법을 보여줍니다.

동일 브랜치의 작업 간 캐시 공유#

각 브랜치의 작업이 동일한 캐시를 사용하도록 하려면 key: $CI_COMMIT_REF_SLUG로 캐시를 정의합니다:

cache:
  key: $CI_COMMIT_REF_SLUG

이 구성은 캐시를 실수로 덮어쓰는 것을 방지합니다. 그러나 머지 리퀘스트의 첫 번째 파이프라인은 느립니다. 브랜치에 커밋이 다음에 푸시되면 캐시가 재사용되고 작업이 더 빠르게 실행됩니다.

작업별 및 브랜치별 캐싱을 활성화하려면:

cache:
  key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"

스테이지별 및 브랜치별 캐싱을 활성화하려면:

cache:
  key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"

다른 브랜치의 작업 간 캐시 공유#

모든 브랜치와 모든 작업에서 캐시를 공유하려면 모든 것에 동일한 키를 사용합니다:

cache:
  key: one-key-to-rule-them-all

브랜치 간에 캐시를 공유하되 각 작업에 고유한 캐시를 사용하려면:

cache:
  key: $CI_JOB_NAME

변수를 사용하여 작업의 캐시 정책 제어#

히스토리
  • GitLab 16.1에서 도입되었습니다.

가져오기 정책만 다른 작업의 중복을 줄이기 위해 CI/CD 변수를 사용할 수 있습니다.

예를 들어:

conditional-policy:
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      variables:
        POLICY: pull-push
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
      variables:
        POLICY: pull
  stage: build
  cache:
    key: gems
    policy: $POLICY
    paths:
      - vendor/bundle
  script:
    - echo "This job pulls and pushes the cache depending on the branch"
    - echo "Downloading dependencies..."

이 예시에서 작업의 캐시 정책은:

  • 기본 브랜치 변경에 대해 pull-push.
  • 다른 브랜치 변경에 대해 pull.

종속성 캐싱#

이 예시들은 프로그래밍 언어별로 일반적인 종속성을 캐싱하는 방법을 보여줍니다.

Node.js#

프로젝트가 Node.js 종속성을 설치하기 위해 npm을 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. 기본적으로 npm은 홈 폴더(~/.npm)에 캐시 데이터를 저장합니다. 그러나 프로젝트 디렉토리 외부의 항목은 캐싱할 수 없습니다. 대신 npm이 ./.npm을 사용하도록 하고 브랜치별로 캐싱합니다:

default:
  image: node:latest
  cache:  # Cache modules in between jobs
    key: $CI_COMMIT_REF_SLUG
    paths:
      - .npm/
  before_script:
    - npm ci --cache .npm --prefer-offline

test_async:
  script:
    - node ./specs/start.js ./specs/async.spec.js

잠금 파일에서 캐시 키 계산#

cache:key:files를 사용하여 package-lock.json 또는 yarn.lock과 같은 잠금 파일에서 캐시 키를 계산하고 여러 작업에서 재사용할 수 있습니다.

default:
  cache:  # Cache modules using lock file
    key:
      files:
        - package-lock.json
    paths:
      - .npm/

오프라인 미러를 사용하는 Yarn#

Yarn을 사용하는 경우, yarn-offline-mirror를 사용하여 압축된 node_modules tarball을 캐싱할 수 있습니다. 압축해야 하는 파일이 적으므로 캐시가 더 빠르게 생성됩니다:

job:
  script:
    - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
    - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
    - yarn install --frozen-lockfile --no-progress
  cache:
    key:
      files:
        - yarn.lock
    paths:
      - .yarn-cache/

PHP#

프로젝트가 PHP 종속성을 설치하기 위해 Composer를 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. PHP 라이브러리 모듈은 vendor/에 설치되고 브랜치별로 캐싱됩니다:

default:
  image: php:latest
  cache:  # Cache libraries in between jobs
    key: $CI_COMMIT_REF_SLUG
    paths:
      - vendor/
  before_script:
    # Install and run Composer
    - curl --show-error --silent "https://getcomposer.org/installer" | php
    - php composer.phar install

test:
  script:
    - vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never

Python#

프로젝트가 Python 종속성을 설치하기 위해 pip를 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. pip의 캐시는 .cache/pip/ 아래에 정의되고 브랜치별로 캐싱됩니다:

default:
  image: python:latest
  cache:                      # Pip's cache doesn't store the python packages
    paths:                    # https://pip.pypa.io/en/stable/topics/caching/
      - .cache/pip
  before_script:
    - python -V               # Print out python version for debugging
    - pip install virtualenv
    - virtualenv venv
    - source venv/bin/activate

variables:  # Change pip's cache directory to be inside the project directory because GitLab can only cache local items.
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

test:
  script:
    - python setup.py test
    - pip install ruff
    - ruff --format=gitlab .

Ruby#

프로젝트가 gem 종속성을 설치하기 위해 Bundler를 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. Gem은 vendor/ruby/에 설치되고 브랜치별로 캐싱됩니다:

default:
  image: ruby:latest
  cache:                                            # Cache gems in between builds
    key: $CI_COMMIT_REF_SLUG
    paths:
      - vendor/ruby
  before_script:
    - ruby -v                                       # Print out ruby version for debugging
    - bundle config set --local path 'vendor/ruby'  # The location to install the specified gems to
    - bundle install -j $(nproc)                    # Install dependencies into ./vendor/ruby

rspec:
  script:
    - rspec spec

다른 gem이 필요한 작업이 있는 경우 전역 cache 정의에서 prefix 키워드를 사용합니다. 이 구성은 각 작업에 대해 다른 캐시를 생성합니다.

예를 들어, 테스트 작업은 프로덕션에 배포하는 작업과 동일한 gem이 필요하지 않을 수 있습니다:

default:
  cache:
    key:
      files:
        - Gemfile.lock
      prefix: $CI_JOB_NAME
    paths:
      - vendor/ruby

test_job:
  stage: test
  before_script:
    - bundle config set --local path 'vendor/ruby'
    - bundle install --without production
  script:
    - bundle exec rspec

deploy_job:
  stage: production
  before_script:
    - bundle config set --local path 'vendor/ruby'   # The location to install the specified gems to
    - bundle install --without test
  script:
    - bundle exec deploy

Go#

프로젝트가 Go 종속성을 설치하기 위해 Go Modules를 사용하는 경우, 다음 예시는 모든 작업이 확장할 수 있는 go-cache 템플릿에 cache를 정의합니다. Go 모듈은 ${GOPATH}/pkg/mod/에 설치되고 모든 go 프로젝트에 대해 캐싱됩니다:

.go-cache:
  variables:
    GOPATH: $CI_PROJECT_DIR/.go
  before_script:
    - mkdir -p .go
  cache:
    paths:
      - .go/pkg/mod/

test:
  image: golang:latest
  extends: .go-cache
  script:
    - go test ./... -v -short

빌드 아티팩트 및 다운로드 캐싱#

이 예시들은 빌드 속도를 높이기 위해 컴파일된 객체와 다운로드된 파일을 캐싱하는 방법을 보여줍니다.

Ccache를 사용한 C/C++ 컴파일 캐싱#

C/C++ 프로젝트를 컴파일하는 경우 Ccache를 사용하여 빌드 시간을 단축할 수 있습니다. Ccache는 이전 컴파일을 캐싱하고 동일한 컴파일이 다시 수행되는 경우를 감지하여 재컴파일 속도를 높입니다. Linux 커널과 같은 대규모 프로젝트를 빌드할 때 상당히 빠른 컴파일을 기대할 수 있습니다.

작업 간에 생성된 캐시를 재사용하려면 cache를 사용합니다. 예를 들어:

job:
  cache:
    paths:
      - ccache
  before_script:
    - export PATH="/usr/lib/ccache:$PATH"  # Override compiler path with ccache (this example is for Debian)
    - export CCACHE_DIR="${CI_PROJECT_DIR}/ccache"
    - export CCACHE_BASEDIR="${CI_PROJECT_DIR}"
    - export CCACHE_COMPILERCHECK=content  # Compiler mtime might change in the container, use checksums instead
  script:
    - ccache --zero-stats || true
    - time make                            # Actually build your code while measuring time and cache efficiency.
    - ccache --show-stats || true

단일 저장소에 여러 프로젝트가 있는 경우 각 프로젝트에 별도의 CCACHE_BASEDIR이 필요하지 않습니다.

cURL로 다운로드 캐싱#

프로젝트가 종속성이나 파일을 다운로드하기 위해 cURL을 사용하는 경우 다운로드된 콘텐츠를 캐싱할 수 있습니다. 최신 다운로드를 사용할 수 있으면 파일이 자동으로 업데이트됩니다.

job:
  script:
    - curl --remote-time --time-cond .curl-cache/caching.md --output .curl-cache/caching.md "https://docs.gitlab.com/ci/caching/"
  cache:
    paths:
      - .curl-cache/

이 예시에서 cURL은 웹 서버에서 파일을 다운로드하고 .curl-cache/의 로컬 파일에 저장합니다. --remote-time 플래그는 서버에서 보고한 마지막 수정 시간을 저장하고, cURL은 --time-cond를 사용하여 캐시된 파일의 타임스탬프와 비교합니다. 원격 파일의 타임스탬프가 더 최신인 경우 로컬 캐시가 자동으로 업데이트됩니다.

CI/CD 캐싱 예시

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

캐싱을 사용하면 작업이 실행될 때마다 종속성과 빌드 아티팩트를 다운로드하지 않아도 됩니다. 더 많은 예시는 GitLab CI/CD 템플릿을 참조하세요. 이 예시들은 작업 및 브랜치 간에 캐시를 공유하는 다양한 접근 방법을 보여줍니다.

캐싱을 사용하면 작업이 실행될 때마다 종속성과 빌드 아티팩트를 다운로드하지 않아도 됩니다. 캐싱은 이전에 다운로드한 콘텐츠를 재사용하여 CI/CD 파이프라인 속도를 높입니다.

더 많은 예시는 GitLab CI/CD 템플릿을 참조하세요.

캐시 전략#

이 예시들은 작업 및 브랜치 간에 캐시를 공유하는 다양한 접근 방법을 보여줍니다.

동일 브랜치의 작업 간 캐시 공유#

각 브랜치의 작업이 동일한 캐시를 사용하도록 하려면 key: $CI_COMMIT_REF_SLUG로 캐시를 정의합니다:

cache:
  key: $CI_COMMIT_REF_SLUG

이 구성은 캐시를 실수로 덮어쓰는 것을 방지합니다. 그러나 머지 리퀘스트의 첫 번째 파이프라인은 느립니다. 브랜치에 커밋이 다음에 푸시되면 캐시가 재사용되고 작업이 더 빠르게 실행됩니다.

작업별 및 브랜치별 캐싱을 활성화하려면:

cache:
  key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"

스테이지별 및 브랜치별 캐싱을 활성화하려면:

cache:
  key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"

다른 브랜치의 작업 간 캐시 공유#

모든 브랜치와 모든 작업에서 캐시를 공유하려면 모든 것에 동일한 키를 사용합니다:

cache:
  key: one-key-to-rule-them-all

브랜치 간에 캐시를 공유하되 각 작업에 고유한 캐시를 사용하려면:

cache:
  key: $CI_JOB_NAME

변수를 사용하여 작업의 캐시 정책 제어#

히스토리
  • GitLab 16.1에서 도입되었습니다.

가져오기 정책만 다른 작업의 중복을 줄이기 위해 CI/CD 변수를 사용할 수 있습니다.

예를 들어:

conditional-policy:
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      variables:
        POLICY: pull-push
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
      variables:
        POLICY: pull
  stage: build
  cache:
    key: gems
    policy: $POLICY
    paths:
      - vendor/bundle
  script:
    - echo "This job pulls and pushes the cache depending on the branch"
    - echo "Downloading dependencies..."

이 예시에서 작업의 캐시 정책은:

  • 기본 브랜치 변경에 대해 pull-push.
  • 다른 브랜치 변경에 대해 pull.

종속성 캐싱#

이 예시들은 프로그래밍 언어별로 일반적인 종속성을 캐싱하는 방법을 보여줍니다.

Node.js#

프로젝트가 Node.js 종속성을 설치하기 위해 npm을 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. 기본적으로 npm은 홈 폴더(~/.npm)에 캐시 데이터를 저장합니다. 그러나 프로젝트 디렉토리 외부의 항목은 캐싱할 수 없습니다. 대신 npm이 ./.npm을 사용하도록 하고 브랜치별로 캐싱합니다:

default:
  image: node:latest
  cache:  # Cache modules in between jobs
    key: $CI_COMMIT_REF_SLUG
    paths:
      - .npm/
  before_script:
    - npm ci --cache .npm --prefer-offline

test_async:
  script:
    - node ./specs/start.js ./specs/async.spec.js

잠금 파일에서 캐시 키 계산#

cache:key:files를 사용하여 package-lock.json 또는 yarn.lock과 같은 잠금 파일에서 캐시 키를 계산하고 여러 작업에서 재사용할 수 있습니다.

default:
  cache:  # Cache modules using lock file
    key:
      files:
        - package-lock.json
    paths:
      - .npm/

오프라인 미러를 사용하는 Yarn#

Yarn을 사용하는 경우, yarn-offline-mirror를 사용하여 압축된 node_modules tarball을 캐싱할 수 있습니다. 압축해야 하는 파일이 적으므로 캐시가 더 빠르게 생성됩니다:

job:
  script:
    - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
    - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
    - yarn install --frozen-lockfile --no-progress
  cache:
    key:
      files:
        - yarn.lock
    paths:
      - .yarn-cache/

PHP#

프로젝트가 PHP 종속성을 설치하기 위해 Composer를 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. PHP 라이브러리 모듈은 vendor/에 설치되고 브랜치별로 캐싱됩니다:

default:
  image: php:latest
  cache:  # Cache libraries in between jobs
    key: $CI_COMMIT_REF_SLUG
    paths:
      - vendor/
  before_script:
    # Install and run Composer
    - curl --show-error --silent "https://getcomposer.org/installer" | php
    - php composer.phar install

test:
  script:
    - vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never

Python#

프로젝트가 Python 종속성을 설치하기 위해 pip를 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. pip의 캐시는 .cache/pip/ 아래에 정의되고 브랜치별로 캐싱됩니다:

default:
  image: python:latest
  cache:                      # Pip's cache doesn't store the python packages
    paths:                    # https://pip.pypa.io/en/stable/topics/caching/
      - .cache/pip
  before_script:
    - python -V               # Print out python version for debugging
    - pip install virtualenv
    - virtualenv venv
    - source venv/bin/activate

variables:  # Change pip's cache directory to be inside the project directory because GitLab can only cache local items.
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

test:
  script:
    - python setup.py test
    - pip install ruff
    - ruff --format=gitlab .

Ruby#

프로젝트가 gem 종속성을 설치하기 위해 Bundler를 사용하는 경우, 다음 예시는 모든 작업이 상속하도록 기본 cache를 정의합니다. Gem은 vendor/ruby/에 설치되고 브랜치별로 캐싱됩니다:

default:
  image: ruby:latest
  cache:                                            # Cache gems in between builds
    key: $CI_COMMIT_REF_SLUG
    paths:
      - vendor/ruby
  before_script:
    - ruby -v                                       # Print out ruby version for debugging
    - bundle config set --local path 'vendor/ruby'  # The location to install the specified gems to
    - bundle install -j $(nproc)                    # Install dependencies into ./vendor/ruby

rspec:
  script:
    - rspec spec

다른 gem이 필요한 작업이 있는 경우 전역 cache 정의에서 prefix 키워드를 사용합니다. 이 구성은 각 작업에 대해 다른 캐시를 생성합니다.

예를 들어, 테스트 작업은 프로덕션에 배포하는 작업과 동일한 gem이 필요하지 않을 수 있습니다:

default:
  cache:
    key:
      files:
        - Gemfile.lock
      prefix: $CI_JOB_NAME
    paths:
      - vendor/ruby

test_job:
  stage: test
  before_script:
    - bundle config set --local path 'vendor/ruby'
    - bundle install --without production
  script:
    - bundle exec rspec

deploy_job:
  stage: production
  before_script:
    - bundle config set --local path 'vendor/ruby'   # The location to install the specified gems to
    - bundle install --without test
  script:
    - bundle exec deploy

Go#

프로젝트가 Go 종속성을 설치하기 위해 Go Modules를 사용하는 경우, 다음 예시는 모든 작업이 확장할 수 있는 go-cache 템플릿에 cache를 정의합니다. Go 모듈은 ${GOPATH}/pkg/mod/에 설치되고 모든 go 프로젝트에 대해 캐싱됩니다:

.go-cache:
  variables:
    GOPATH: $CI_PROJECT_DIR/.go
  before_script:
    - mkdir -p .go
  cache:
    paths:
      - .go/pkg/mod/

test:
  image: golang:latest
  extends: .go-cache
  script:
    - go test ./... -v -short

빌드 아티팩트 및 다운로드 캐싱#

이 예시들은 빌드 속도를 높이기 위해 컴파일된 객체와 다운로드된 파일을 캐싱하는 방법을 보여줍니다.

Ccache를 사용한 C/C++ 컴파일 캐싱#

C/C++ 프로젝트를 컴파일하는 경우 Ccache를 사용하여 빌드 시간을 단축할 수 있습니다. Ccache는 이전 컴파일을 캐싱하고 동일한 컴파일이 다시 수행되는 경우를 감지하여 재컴파일 속도를 높입니다. Linux 커널과 같은 대규모 프로젝트를 빌드할 때 상당히 빠른 컴파일을 기대할 수 있습니다.

작업 간에 생성된 캐시를 재사용하려면 cache를 사용합니다. 예를 들어:

job:
  cache:
    paths:
      - ccache
  before_script:
    - export PATH="/usr/lib/ccache:$PATH"  # Override compiler path with ccache (this example is for Debian)
    - export CCACHE_DIR="${CI_PROJECT_DIR}/ccache"
    - export CCACHE_BASEDIR="${CI_PROJECT_DIR}"
    - export CCACHE_COMPILERCHECK=content  # Compiler mtime might change in the container, use checksums instead
  script:
    - ccache --zero-stats || true
    - time make                            # Actually build your code while measuring time and cache efficiency.
    - ccache --show-stats || true

단일 저장소에 여러 프로젝트가 있는 경우 각 프로젝트에 별도의 CCACHE_BASEDIR이 필요하지 않습니다.

cURL로 다운로드 캐싱#

프로젝트가 종속성이나 파일을 다운로드하기 위해 cURL을 사용하는 경우 다운로드된 콘텐츠를 캐싱할 수 있습니다. 최신 다운로드를 사용할 수 있으면 파일이 자동으로 업데이트됩니다.

job:
  script:
    - curl --remote-time --time-cond .curl-cache/caching.md --output .curl-cache/caching.md "https://docs.gitlab.com/ci/caching/"
  cache:
    paths:
      - .curl-cache/

이 예시에서 cURL은 웹 서버에서 파일을 다운로드하고 .curl-cache/의 로컬 파일에 저장합니다. --remote-time 플래그는 서버에서 보고한 마지막 수정 시간을 저장하고, cURL은 --time-cond를 사용하여 캐시된 파일의 타임스탬프와 비교합니다. 원격 파일의 타임스탬프가 더 최신인 경우 로컬 캐시가 자동으로 업데이트됩니다.