← 전체 글로 돌아가기

CI/CD

GitHub Actions에서 캐시로 빌드 시간을 줄이는 방법

actions/cache를 제대로 설정하면 npm install 단계를 건너뛸 수 있다. 캐시 키 설계가 핵심이다.

GitHub Actions 워크플로가 느리면 제일 먼저 볼 곳이 의존성 설치 단계다. npm install이나 pip install은 한 번 실행하면 수십 초에서 몇 분이 걸리는데, 이걸 매 푸시마다 반복하면 낭비다.

actions/cache 기본 사용

- name: Cache npm
  uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-npm-

key는 캐시를 저장하고 찾을 이름이다. hashFilespackage-lock.json의 해시를 포함하면 의존성이 바뀔 때만 캐시가 무효화된다. 바뀌지 않았으면 캐시를 그대로 쓴다.

restore-keys는 정확한 키로 캐시를 못 찾았을 때 부분 매칭으로 가장 최근 캐시를 복원하는 fallback이다. 완전히 새로 설치하는 것보다는 훨씬 빠르다.

npm ci와 함께 쓸 때

- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
    restore-keys: ${{ runner.os }}-npm-

- name: Install dependencies
  run: npm ci

node_modules 자체보다 ~/.npm(npm 전역 캐시)를 캐시하는 게 더 안정적이다. node_modules를 캐시하면 OS나 Node 버전이 다를 때 문제가 생길 수 있다.

캐시가 제대로 동작하는지 확인하는 방법

Actions 탭에서 워크플로 실행 로그를 열면 캐시 단계에서 Cache restored from key: 또는 Cache not found for input keys:가 표시된다. 히트가 안 된다면 키 설계를 다시 보면 된다.

캐시 크기 한도는 저장소당 10GB이고, 7일 동안 사용되지 않은 캐시는 자동으로 삭제된다.

Docker 레이어 캐시

Docker 이미지를 빌드하는 워크플로라면 BuildKit 캐시를 활용한다.

- name: Build Docker image
  uses: docker/build-push-action@v5
  with:
    context: .
    push: false
    cache-from: type=gha
    cache-to: type=gha,mode=max

type=gha는 GitHub Actions 캐시 스토리지를 Docker layer 캐시로 사용한다. Dockerfile을 바꾸지 않은 레이어는 캐시에서 바로 가져오므로 전체 빌드 시간이 크게 줄어든다. mode=max를 쓰면 모든 레이어를 캐시하고, mode=min은 최종 이미지 레이어만 캐시한다.