[DevOps] 4-1. GitHub Actions로 Next.js build하기

jinni·2025년 11월 17일

DevOps

목록 보기
6/6

Oracle free tire instance를 사용해서 프론트엔드 프로젝트를 배포하여 운영하는 과정에서 freetire instance의 컴퓨팅 파워가 Next.js 프로젝트를 빌드하는 것이 어렵다는 것을 알게되었다.

⚠ Slow filesystem detected. The benchmark took 238ms. If /home/ubuntu/test/.next is a network drive, consider moving it to a local folder. If you have an antivirus enabled, consider excluding your project directory.

Next.js는 빌드 시작 시 내부적으로 작은 파일을 .next 폴더에 쓰고, 다시 읽어오는 "벤치마크 테스트"를 실행한다고 한다.
이 I/O 테스트가 일정시간을 초과하면 위 경고를 띄운다.

chatgpt에게 해결할 수 있는 방법을 물어보고 다양한 시도를 해보았지만, free tire instance에서 Next.js를 빌드하는데에는 실패했다. (정말 실패하는지는 모르겠다. 인내심을 이기지 못하고 중단했기 때문에, 하지만 운영환경에서 이런 속도로 진행된다면 사용할 수 없다.)

Next.js 빌드가 하는 일

next build 명령어는 단순한 JS 번들링이 아니라, 정적 분석 + SSR용 번들 생성 + 최적화 파이프라인을 모두 수행한다고 한다.

빌드 과정
1. Page Graph 생성: 모든 /pages 또는 /app 트리 스캔
2. Webpack 번들링: 각 페이지별 SSR 번들, 클라이언트 번들을 각각 생성
3. SWC(Rust 기반 트랜스파일러)로 변환 및 압축
4. Image Optimization, Font Optimization 등 추가 플러그인 처리
5. .next/cache, .next/server, .next/static 등에 수천 개의 파일 생성.
6. 메타데이터 및 라우팅 맵 빌드

즉, CPU, RAM, 디스크 I/O를 모두 적극적으로 사용한다.

Oracle freetire instance의 사양

항목Next.js 빌드 요구치
vCPU1개 (1/8 또는 1/4 core 할당)최소 2 vCPU 이상 권장
RAM1GB ~ 2GB최소 2~4GB 이상 필요
Disk IOPS약 100~200 IOPSwebpack은 수천 IOPS 수준 사용
Disk Throughput20~40MB/sNext.js 빌드 시 100MB/s 이상 필요
Swap없음 (기본 비활성화)없으면 OOM으로 빌드 중단 가능

즉, free tire 환경에서 Next.js 프로젝트를 빌드하기에는 버겁다.

GitHub Actions로 Next.js 빌드 후 결과를 instance로 전송

이 문제를 해결하는 방법으로, GitHub Actions에서 Next.js를 빌드하고 next start에 필요한 파일만을 instance에 rsync 하는 방법으로 해결하였다.

Workflow 작성하기

name: Build and Deploy to Ubuntu Server

on:
  push:
    branches:
      - main
      - cicd
  workflow_dispatch: # 수동 실행 전용

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      # 저장소 체크아웃
      - name: Checkout repository
        uses: actions/checkout@v4

      # Node.js + pnpm 설치
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "18"

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          run_install: false

      # 의존성 설치 및 빌드
      - name: Install dependencies and build Next.js
        run: |
          pnpm install --frozen-lockfile
          pnpm build

      # rsync 설치
      - name: Install rsync
        run: sudo apt-get update && sudo apt-get install -y rsync openssh-client

      # .next 폴더 서버로 전송
      - name: Sync .next folder to Oracle Instance
        env:
          SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
        run: |
          echo "$SSH_KEY" > /tmp/deploy_key
          chmod 600 /tmp/deploy_key

          # 스크립트 종료 시(성공/실패 무관) SSH 키 파일 정리
          trap 'rm -f /tmp/deploy_key' EXIT

          rsync -avz --delete -e "ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no" \
            .next/ \
            ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/ubuntu/test/.next/

          rsync -avz --delete -e "ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no" \
            public/ \
            ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/ubuntu/test/public/

          rsync -avz -e "ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no" \
            package.json \
            pnpm-lock.yaml \
            next.config.ts \
            tsconfig.json \
            ecosystem.config.js \
            ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/ubuntu/test/

GitHub Actions의 가상 환경에 프로젝트 빌드에 필요한 Node.js, pnpm 플러그인을 사용하여 빌드하고, rsync install하여 ssh로 .next, package.json 등의 파일을 전송하였다.

0개의 댓글