CI : Nx monorepo 빌드시간 줄이기

seoyeonpp·2025년 2월 6일

Monorepo

목록 보기
5/5

이전 글 보기

github actions에서 빌드 시간을 확인해봤을때,
3개의 앱을 빌드하는데, 거의 7~10분 정도 걸렸다.
또 Docker Container 를 빌드해서 AWS ECR에 배포하는데 6분이 넘게 걸려서 총 ci 실행시간이 15~20분이 걸렸다.

무슨 한번 배포하는데 최소 15분이 걸리다니..
너무 느려서 방법이 없을까 찾아봤다.

이전 글에서 사용했던 cache 방법은 pnpm 설치를 캐싱하는거라, 앱 빌드에는 적용되지않았다.
그래서 다른 방법을 찾아보다가..

https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow

matrix라는 방법을 발견했다!

matrix는 행렬이라는 뜻인데, 병렬로 각각의 배열 항목에 job을 실행한다.
병렬로 실행되길 원하는 jobs 에다가 strategy.matrix 로 원하는 변수에다가 배열을 넘기면 되는거였다.

기존에는 Build를
pnpm nx affected --target=build --base=$BASE_BRANCH --head=HEAD --parallel=3
이렇게 nx 에서 제공하는 수정된 프로젝트만 빌드하는 명령어를 썼었는데, 여기서 parallel을 지정하면 병렬로 빌드가 된다고 했다.
근데 내가 세팅을 잘못한건지 병렬빌드가 안되고 3개의 프로젝트가 동기적으로 하나씩 빌드가 되었다.

근데 matrix를 쓰면 병렬로 job들이 실행되니까 빌드시간을 줄일수있을것같았다.

그래서 원래의 ci.yml을 이렇게 수정해봤다! ☺️

  • nx affected project로 수정된 앱을 확인해서 $GITHUB_OUTPUT 으로 배열을 저장한다.
  • build job에 해당 배열을 matrix로 지정한다.
  • 기존에 Docker 컨테이너를 push 하는 부분은 for문을 돌려서 배열 항목을 순회하고있었는데, 반복문을 지우고
    ${{ matrix.project }} 로 적는다.

사용하는 예시 코드는

build:
    name: Build & Push Docker Image
    runs-on: self-hosted
    needs: [prepare, setting]
    strategy:
      matrix:
        project: ${{ fromJson(needs.setting.outputs.PROJECTS_JSON) }}
        .
        .
        .
   - name: Build affected projects
        run: |
          pnpm nx build ${{ matrix.project }} --configuration=$BUILD_ENV
        env:
          NX_NO_CLOUD: true

이런식으로 써줬다.

그랬더니 엄청난 변화가 일어났다!!!

matrix 전략을 쓰기 전

Build와 Docker를 다른 step에 지정했었다.
Build : 11분 43초
Docker Build & Push : 7분 56초
걸린 시간: 19분 39초

matrix 전략 쓴 후

Build와 Docker Build, Push를 matrix를 활용해서 1개의 step안에서 처리했다.
Build + Docker Build + Docker Push : 각각 4분~7분
걸린 시간: 7분 9초 (병렬로 실행되어서 제일 오래걸린 프로젝트 기준)

이렇게 확인해보니 엄청난 차이였다.
기존에 20분정도 걸리던 걸 7분대로 줄였다!!

같이 일하는 개발자분들이 엄청나게 좋아하셔서 더 좋았다 ㅎㅎ

ci를 어떻게 구성하는지에 따라 이렇게 빨라지는걸 보니 진짜 신기하다!

0개의 댓글