개요
현재 회사에서는 Next.js 프로젝트에 CodePipeline, CodeBuild 를 활용한 CI/CD 가 구축되어 있다.
CodeBuild 와 yarn classic 을 활용해 배포를 진행하게 되면 빌드 + 배포 시간이 평균 9분이 넘어간다.
예전에 Vercel 에서 빌드 + 배포를 진행했을 때 3분대가 나왔던 거랑 비교하면 9분이라는 굉장히 큰 시간을 빌드 + 배포에 쓰고 있다.
이를 줄여보고자 CodeBuild 의 S3 캐시와 yarn classic 을 pnpm 로 마이그레이션 하는 등 시도를 해봤다.
결론부터 말하자면 pnpm + S3 캐시를 도입 후 빌드+배포 시간이 평균 554초에서 평균 392초대로 25%가 감소했다.
yarn 에서 pnpm 으로
pnpm 설치
우선 pnpm 을 설치해야 한다. 공식문서에 여러 방법이 설명되어있지만 이 글에서는 corepack 을 활용한다.
corepack 을 사용하기 위해서는 node 16.13 버전 이상이 필요하다.
$ corepack enable $ pnpm -v
node_modules 삭제
npkill
을 활용하여 프로젝트의 모든 node_modules 를 삭제한다.$ npx npkill
pnpm import
pnpm import
를 활용해 기존 lockfile 로 부터pnpm-lock.yaml
을 생성한다.$ pnpm import
pnpm import
후 기존 lockfile만약 모노레포를 사용중이라면
pnpm-workspace.yaml
을 미리 생성해야 한다.# pnpm-workspace.yaml packages: # all packages in direct subdirs of packages/ - 'apps/*' # all packages in subdirs of components/ - 'components/**' # exclude packages that are inside test directories - '!**/test/**'
의존성 설치
$ pnpm install
추가로
package.json
에packageManager
필드를 추가 하면 다른 환경에서 같은 pnpm 버전을 사용할 수 있다.// package.json { "packageManager": "pnpm@<version>" }
자세한 내용은 node 공식문서에서 확인 할 수 있다.
이를 buildspec.yaml
에 적용하면 아래와 같은 코드가 된다.
# buildspec.yaml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
# pnpm 사용
- corepack enable
- pnpm -v
- pnpm install --frozen-lockfile
build:
commands:
# 혹은 모노레포를 사용중이라면 `pnpm -F <package-name> run build`
- pnpm run build
CodeBuild 에 S3 캐시 적용하기
우선 S3 캐시를 적용할 CodeBuild 프로젝트 상세 페이지에 접속한다.
상세 콘솔에서 Edit > Artifacts
메뉴에 들어간다.
하단의 Additional configuration
을 확장해 보면 Cache Type
이 No Cache
로 설정되어 있는 걸 확인 할 수 있다.
위 이미지와 같이 Cache Type
을 Amazon S3
로 변경한 뒤 Cache bucket
과 Cache path prefix
를 설정한다.
CodeBuild, pnpm 캐시 트러블 슈팅
트러블 슈팅으로 고생했는데, cache paths 에 node_modules
를 입력하면 S3 캐시 업로드가 진행이 되지 않는 이슈가 있었다. 이는 pnpm 이 기본적으로 의존성을 심볼릭 링크 방식을 사용함에 있어서 생기는 이슈였고, S3 는 심볼릭 링크 업로드를 지원하지 않는다.
해결 방법은 pnpm 의 공식 문서를 보다 찾게 되었다.
공통으로 pnpm config set store-dir <path>
부분이 자주 보이는데, 이를 buildspec.yaml
에 적용해 보니 S3 캐시 업로드가 정상적으로 진행이 되었다.
pnpm store 와 캐시를 추가하면 아래와 같은 코드가 된다.
# buildspec.yaml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
- corepack enable
- pnpm -v
# pnpm store 위치 설정
- pnpm config set store-dir .pnpm-store
- pnpm install --frozen-lockfile
build:
commands:
- pnpm run build
# Cache 추가
cache:
paths:
- '.pnpm-store/**/*'
- '.next/cache/**/*'
결론
- | 평균 초 | 빌드 + 배포 횟수 |
yarn + No Cache | 554 | 57 |
yarn + No Cache (최근 10회) | 490 | 10 |
pnpm + No Cache | 428 | 3 |
pnpm + Cache(pnpm) | 408 | 3 |
pnpm + Cache(pnpm, Next.js) | 392 | 2 |
아직 테스트 수가 적어서 더 지켜봐야 정확한 판단 가능하겠지만 당장 결과를 본다면,
yarn → pnpm 으로 변경한 것만으로 Install 시간이 전체 평균 25%(162초), 최근 평균 12%(98초) 정도 감소했고, S3 캐시를 도입했을 때 평균 9%(30초) 정도 줄어들었다.
충분히 pnpm + S3 캐시를 도입할 가치는 있어 보인다.