CI/CD 캐싱 예시
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를 사용하여 캐시된 파일의 타임스탬프와 비교합니다. 원격 파일의 타임스탬프가 더 최신인 경우 로컬 캐시가 자동으로 업데이트됩니다.
