상세 컨텐츠

본문 제목

[IT] Next.js 자동 배포 파이프라인 구축하기

[IT]

by @Point_B 2026. 4. 1. 19:30

본문

GitHub Actions로 Next.js 프로젝트 자동 배포 파이프라인 구축하기 (feat. Vercel + Slack 알림)

2025년 1월 · CI/CD · DevOps · Next.js · 약 15분 읽기

PR 올릴 때마다 수동으로 빌드하고 배포하는 거 지치셨나요? 이 글에서는 GitHub Actions를 이용해서 main 브랜치에 머지되는 순간 자동으로 빌드 → 테스트 → 배포 → Slack 알림까지 이어지는 파이프라인을 구성하는 방법을 다룹니다.

이 글에서 다루는 스택: Next.js 14 / pnpm / Vercel / GitHub Actions / Slack Webhook

전체 파이프라인 구조

구성하려는 파이프라인의 흐름은 다음과 같습니다.

  1. PR 생성 시 → lint + type-check + 테스트 자동 실행
  2. main 머지 시 → Vercel 프로덕션 배포 트리거
  3. 배포 완료 후 → Slack 채널에 결과 알림 전송

1 디렉토리 구조

프로젝트 루트에 .github/workflows/ 폴더를 만들고 두 개의 워크플로우 파일을 생성합니다.

my-next-app/
├── .github/
│ └── workflows/
│ ├── ci.yml        # PR 생성 시 lint + test
│ └── deploy.yml   # main 머지 시 배포 + 알림
├── src/
├── package.json
└── pnpm-lock.yaml

2 CI 워크플로우 (PR 검증)

PR이 열리거나 업데이트될 때마다 lint, 타입 체크, 테스트를 자동으로 실행합니다. pnpm 캐시를 활용해서 의존성 설치 시간을 줄이는 게 포인트입니다.

.github/workflows/ci.yml
name: CI

on:
  pull_request:
    branches: [main, develop]

jobs:
  ci:
    name: Lint & Test
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: 8

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Run ESLint
        run: pnpm lint

      - name: Run type check
        run: pnpm tsc --noEmit

      - name: Run tests
        run: pnpm test --passWithNoTests

      - name: Build check
        run: pnpm build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
주의: --frozen-lockfile 옵션은 lockfile이 package.json과 맞지 않으면 에러를 냅니다. 의존성 추가 후 lockfile 커밋을 빠뜨리면 CI가 깨지므로 주의하세요.

3 배포 워크플로우 (main 머지 시)

main 브랜치에 push가 발생하면 Vercel CLI를 통해 프로덕션 배포를 수행하고, 성공/실패 여부를 Slack으로 알립니다.

.github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]

env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    outputs:
      deploy_url: ${{ steps.deploy.outputs.url }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: 8

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Install Vercel CLI
        run: pnpm add -g vercel@latest

      - name: Pull Vercel environment
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

      - name: Build project
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy to Vercel
        id: deploy
        run: |
          url=$(vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }})
          echo "url=$url" >> $GITHUB_OUTPUT

  notify:
    name: Slack Notify
    runs-on: ubuntu-latest
    needs: deploy
    if: always()

    steps:
      - name: Notify success
        if: needs.deploy.result == 'success'
        uses: slackapi/slack-github-action@v1.26.0
        with:
          payload: |
            {
              "text": ":white_check_mark: *프로덕션 배포 성공*",
              "attachments": [{
                "color": "good",
                "fields": [
                  { "title": "배포 URL", "value": "${{ needs.deploy.outputs.deploy_url }}", "short": false },
                  { "title": "커밋", "value": "${{ github.event.head_commit.message }}", "short": false },
                  { "title": "배포자", "value": "${{ github.actor }}", "short": true }
                ]
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

      - name: Notify failure
        if: needs.deploy.result == 'failure'
        uses: slackapi/slack-github-action@v1.26.0
        with:
          payload: |
            {
              "text": ":x: *프로덕션 배포 실패*",
              "attachments": [{
                "color": "danger",
                "fields": [
                  { "title": "커밋", "value": "${{ github.event.head_commit.message }}", "short": false },
                  { "title": "배포자", "value": "${{ github.actor }}", "short": true },
                  { "title": "Actions 로그", "value": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "short": false }
                ]
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

4 GitHub Secrets 등록

Settings → Secrets and variables → Actions 에서 아래 시크릿을 등록해야 합니다.

등록 필요한 Secrets
VERCEL_TOKEN          # Vercel → Account Settings → Tokens
VERCEL_ORG_ID         # vercel link 실행 후 .vercel/project.json 에서 확인
VERCEL_PROJECT_ID     # 동일 파일에서 확인
SLACK_WEBHOOK_URL     # Slack → 앱 → Incoming Webhooks → Add
NEXT_PUBLIC_API_URL   # 프로젝트에서 사용하는 환경변수들

Vercel 토큰 & ID 빠르게 얻는 법

터미널
# Vercel CLI 설치 (이미 있으면 skip)
npm i -g vercel

# 프로젝트 루트에서 실행
vercel link

# .vercel/project.json 생성됨 → orgId, projectId 복사
cat .vercel/project.json

5 package.json 스크립트 확인

워크플로우에서 사용하는 pnpm lint, pnpm test 스크립트가 정의되어 있어야 합니다.

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint && eslint . --ext .ts,.tsx",
    "test": "jest --ci",
    "type-check": "tsc --noEmit"
  }
}

6 선택: PR에 배포 URL 자동 코멘트

PR마다 preview 배포 URL을 자동으로 댓글로 달아주면 리뷰어가 바로 확인할 수 있어서 편합니다.

.github/workflows/ci.yml 에 추가
      - name: Deploy preview to Vercel
        id: preview
        run: |
          vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
          vercel build --token=${{ secrets.VERCEL_TOKEN }}
          url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
          echo "url=$url" >> $GITHUB_OUTPUT

      - name: Comment PR with preview URL
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `🚀 **Preview 배포 완료**\n\n${process.env.PREVIEW_URL}\n\n> 커밋: ${context.sha.substring(0, 7)}`
            })
        env:
          PREVIEW_URL: ${{ steps.preview.outputs.url }}

마무리

이 파이프라인을 적용하면 개발 흐름이 이렇게 됩니다.

  1. 기능 브랜치에서 작업 후 PR 오픈 → CI 자동 실행 + Preview URL 댓글
  2. 코드 리뷰 후 main 머지 → 프로덕션 자동 배포
  3. 배포 결과 Slack 알림 → 팀 전체가 인지

수동 배포에서 오는 실수와 스트레스를 없애고 싶은 분들께 도움이 됐으면 합니다. 질문은 댓글로!

 
#GitHub Actions #Next.js #CI/CD #Vercel #DevOps #자동배포 #pnpm #Slack #프론트엔드 #개발자블로그

[IT] 2026년 IT 트렌드 TOP 3: 단순 코딩을 넘어 에이전트의 시대로

 

[IT] 2026년 IT 트렌드 TOP 3: 단순 코딩을 넘어 에이전트의 시대로

안녕하세요! 오늘은 급변하는 기술 생태계 속에서 우리 개발자들이 단순한 '구현자'를 넘어 '설계자'로서 어떤 흐름을 읽어야 할지, 2026년 최신 개발 트렌드 3가지를 정리해 보았습니다.1. 생성형

tjdgud246.tistory.com

 

관련글 더보기

🎮 Gravity 게임하기 🎮 2048 게임하기 💬 Comming Soon...