hi-hoi

AWS Amplify에서 Next.js 모노레포 빌드 시간 40% 단축하기 (8분 → 5분)

TL;DR

AWS Amplify에서 Next.js 모노레포 빌드 시간이 평균 8분 이상 소요되고 있었습니다.

빌드 로그 분석 결과 주요 병목은 다음 세 가지였습니다.

  • Submodule 인증 과정
  • 전체 의존성 설치
  • node_modules 캐시

이를 개선해 빌드 시간을 8분 → 5분 초반(약 40% 이상)까지 단축했습니다.


문제 상황

회사 프론트엔드 코드는 모노레포 환경으로 관리되고 있습니다.

서비스는 다음과 같은 구조입니다.

  • Next.js 기반 서비스
  • Vite 기반 서비스

AWS Amplify 배포 환경에서 빌드 시간이 예상보다 길어지는 문제가 있었습니다.

서비스평균 빌드 시간
Next.js약 8분
Vite약 5분

파이프라인은 과거 최적화 이후 큰 변경 없이 유지되고 있었습니다.

지난 최적화 이후 모노레포 구조의 도입과 패키지 매니저의 변경 (npm → pnpm)을 진행했습니다. 이 과정에서 기존 최적화 설정 일부가 깨진 상태였습니다.


빌드 병목 분석 및 개선

Amplify 빌드 로그를 기준으로 병목을 파악하고 개선하려고 했습니다.

로그 분석 결과 컴파일이 아닌, 준비 단계에서 낭비되는 시간이 길었습니다.

1. Submodule 인증 구조 개선

기존 구조

기존 Amplify 빌드 파이프라인에서는 Submodule 동기화에 이런 작업들을 진행했습니다.

→ jq 설치

→ Secrets Manager API

→ token fetch

→ https rewrite

→ git submodule sync

왜 이런 불필요하게 보이는 작업들이 필요했던 건지 궁금해서 사내 위키를 찾아봤습니다. 당시에는 다음과 같은 인식이 있었습니다.

"Amplify CI 환경에서는 SSH 인증을 사용할 수 없다."

이 말은 사실이 아닙니다.

Amplify는 최초에 연결된 GitHub 레포지토리에 대해서만 접근 권한을 가지며, 기본적으로는 Submodule로 연결된 다른 GitHub 레포지토리에 접근할 수 없습니다. 여기서 오해가 생겨서 SSH를 https로 치환하는 작업을 했던 것으로 추정됩니다.

즉, 저는 Amplify에서 SSH 사용이 불가능한 것이 아니라 접근 권한 범위의 문제였을 것으로 판단했습니다.


해결 방법

이 문제는 Deploy Key 기반 SSH 인증으로 해결할 수 있습니다.

  • Submodule Repository → Deploy Key 등록 (SSH Public Key)

  • Amplify → Private Key 환경 변수 설정 → SSH 기반 Submodule 접근

  • 시크릿 매니저로 관리하던 https 접근 토큰을 삭제

이 방식으로 다음 문제를 모두 해결했습니다.

  • Secrets Manager 호출 제거
  • jq 설치 제거
  • .gitmodules rewrite 제거
  • 로컬 / CI 인증 방식 일치

결과

제거한 작업시간
yum + jq 설치24초
Secrets Manager API13초
https rewrite1초
  • 약 40~50초 시간 개선

2. 모노레포 의존성 설치 최적화

기존 방식

pnpm install --frozen-lockfile

이 명령은 모노레포 전체 패키지를 설치합니다.

개선

빌드 대상 서비스만 설치하도록 변경했습니다.

pnpm install --filter "@inf/web..." --frozen-lockfile

결과

빌드 시간은 약 8~9초 단축되었습니다.

예상보다 체감 성능 개선은 크지 않았습니다.

성능 개선이 크지 않았던 이유

  • 서비스 간 공통 의존성 공유율이 높음
  • pnpm의 하드 링크 구조가 이미 매우 빠름

하지만 다음 장점이 있습니다.

  • Phantom Dependency 방지
  • 빌드 파이프라인 정합성 확보
  • 불필요한 패키지 설치 차단

3. 캐시 전략 개선

기존 방식

기존 캐시 전략으로 node_modules 전체에 캐시를 사용 중이었습니다.

캐시를 위해서는 압축 → 다운로드 → 압축 해제 → 업로드 과정이 필요합니다.

pnpm의 node_modules 구조는 symlink + hard link 기반입니다. node_modules 전체를 캐시하면 매우 많은 파일 I/O가 발생하고 캐시 과정 자체가 병목이 될 수 있습니다.

실제로 캐시 관련 작업에 약 2분 이상이 소요되고 있었습니다.

개선

  • node_modules 캐시를 제거하고 pnpm store만 캐시하도록 변경했습니다.
  • Amplify 네트워크 속도가 빠르기 때문에 캐시 미사용 전략도 고려했습니다. 서비스별로 세 번 정도 테스트한 결과, 캐시를 사용할 때 미약한 성능 향상이 있었기에 pnpm-store 캐시는 유지했습니다.

결과

빌드 성능은 다음과 같이 개선되었습니다. (배포 오버헤드 제외)

서비스AS-ISTO-BE개선율
BIZ-WEB8분5분 15초34%
BO-WEB5분2분 55초42%
INF-WEB8분5분 10초35%

Phase별 성능 변화

Phase (빌드 단계)AS-ISTO-BE단축 시간주요 원인
사전 준비 & 캐시 추출1분 11초15초-56초무거운 node_modules 캐시 제거
인증 & 의존성 설치1분 40초43초-57초jq 설치 및 API 호출 제거
Build (컴파일)2분 19초2분 18초-1초Next.js 빌드 자체는 동일
캐시 생성 & 업로드1분 47초36초-1분 11초node_modules 압축 제거
순수 스크립트 실행 시간6분 57초4분 8초-2분 49초

참고: 위 표의 시간은 특정 서비스(@inf/web) 한 개의 Amplify 빌드 파이프라인 동작 시간 기준입니다. 컨테이너 프로비저닝, 내부 환경 캐싱, 배포 등은 제외했습니다.


정리

이번 최적화를 통해 다음과 같은 개선이 이루어졌습니다.

Submodule 인증 구조

Secrets Manager 기반 토큰 → Deploy Key 기반 SSH

모노레포 의존성 설치

pnpm install → pnpm install --filter

캐시 전략

node_modules 캐시 → pnpm store 캐시


Appendix: Amplify 설정 예시

  • 실제 Amplify 설정의 구조를 단순화한 예시입니다.
frontend:
  phases:
    preBuild:
      commands:
        # Deploy Key 기반 SSH 인증
        - mkdir -p ~/.ssh
        - printf '%s' "$DEPLOY_KEY_BASE64" > ~/.ssh/key.base64
        - base64 --decode ~/.ssh/key.base64 > ~/.ssh/id_rsa
        - chmod 600 ~/.ssh/id_rsa
        - ssh-keyscan github.com >> ~/.ssh/known_hosts
 
        # Submodule 동기화
        - git submodule sync
        - git submodule update --init --recursive
 
        # pnpm 환경 준비
        - corepack enable pnpm
 
        # 모노레포 의존성 설치 (target service only)
        - pnpm install --filter "@inf/web..." --frozen-lockfile
 
    build:
      commands:
        - pnpm run build
 
  cache:
    paths:
      - ~/.pnpm-store/**/*
      - .next/cache/**

인사이트

이번 작업을 통해 몇 가지 흥미로운 점을 확인할 수 있었습니다.

  • CI/CD 파이프라인은 한 번 구축되면 장기간 방치되기 쉽다
  • node_modules 캐시는 항상 성능 향상을 보장하지 않는다
  • pnpm은 이미 상당히 최적화된 구조를 가지고 있다
  • AWS Amplify에서도 SSH 인증을 충분히 활용할 수 있다

빌드 로그를 기반으로 병목을 분석하고 개선하는 과정에서 많은 인사이트를 얻을 수 있었습니다.

비슷한 환경에서 Amplify CI/CD를 운영하고 있다면 빌드 로그를 한 번 확인해보는 것도 좋은 출발점이 될 것 같습니다.

긴 글 읽어주셔서 감사합니다.