포스트

[이제와서 시작하는 Next.js 마스터하기 #11] 배포 전략과 CI/CD

[이제와서 시작하는 Next.js 마스터하기 #11] 배포 전략과 CI/CD

“로컬에서 프로덕션까지!” - 클릭 몇 번으로 전 세계에 배포하세요!

🎯 이 글에서 배울 내용

  • Vercel로 빠른 배포
  • Docker 컨테이너화
  • GitHub Actions CI/CD
  • 환경 변수 관리
  • 성능 모니터링

예상 소요 시간: 45분


🚀 Vercel 배포 (가장 쉬움)

1. GitHub 연결

  1. vercel.com 가입
  2. “New Project” 클릭
  3. GitHub 레포지토리 선택
  4. “Deploy” 클릭
  5. 완료! 🎉

자동 배포:

  • main 브랜치 푸시 → 자동 배포
  • PR 생성 → 미리보기 URL 생성

2. 환경 변수 설정

Vercel 대시보드에서:

1
2
3
4
5
Settings → Environment Variables

DATABASE_URL=your-database-url
NEXTAUTH_SECRET=your-secret
GOOGLE_CLIENT_ID=your-google-id

3. 도메인 연결

1
2
3
4
Settings → Domains
→ Add Domain
→ 도메인 입력 (예: mysite.com)
→ DNS 설정 완료

🐳 Docker 배포

1. Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Dockerfile
FROM node:20-alpine AS base

# Dependencies
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json* ./
RUN npm ci

# Builder
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN npm run build

# Runner
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

2. next.config.js

1
2
3
4
// next.config.js
module.exports = {
  output: 'standalone',
};

3. 빌드 및 실행

1
2
3
4
5
6
7
8
# 이미지 빌드
docker build -t my-nextjs-app .

# 컨테이너 실행
docker run -p 3000:3000 \
  -e DATABASE_URL="your-db-url" \
  -e NEXTAUTH_SECRET="your-secret" \
  my-nextjs-app

4. docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/mydb
      - NEXTAUTH_SECRET=your-secret
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
1
2
# 실행
docker-compose up -d

🔄 GitHub Actions CI/CD

1. 테스트 및 빌드

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

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

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Build
        run: npm run build

2. Vercel 자동 배포

name: Deploy to Vercel

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: $
          vercel-org-id: $
          vercel-project-id: $
          vercel-args: '--prod'

🔐 환경 변수 관리

1. .env 파일 구조

1
2
3
.env                  # 로컬 개발 (git ignore)
.env.example          # 예시 파일 (git 포함)
.env.production       # 프로덕션 (git ignore)

2. .env.example

# Database
DATABASE_URL="postgresql://..."

# Authentication
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="generate-a-secret-key"

# OAuth
GOOGLE_CLIENT_ID="your-client-id"
GOOGLE_CLIENT_SECRET="your-client-secret"

3. 환경별 설정

1
2
3
4
5
6
7
8
9
10
11
// lib/config.ts
const config = {
  development: {
    apiUrl: 'http://localhost:3000/api',
  },
  production: {
    apiUrl: 'https://mysite.com/api',
  },
};

export default config[process.env.NODE_ENV || 'development'];

📊 성능 모니터링

1. Vercel Analytics

1
2
3
4
5
6
7
8
9
10
11
12
13
// app/layout.js
import { Analytics } from '@vercel/analytics/react';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  );
}

2. 성능 체크리스트

1
2
3
4
5
6
# Lighthouse 점수 확인
npm install -g lighthouse
lighthouse https://mysite.com --view

# Bundle 크기 분석
npm install -g @next/bundle-analyzer

🎯 오늘 배운 내용 정리

  1. Vercel 배포
    • GitHub 연결
    • 자동 배포
    • 환경 변수
  2. Docker
    • 컨테이너화
    • docker-compose
  3. CI/CD
    • GitHub Actions
    • 자동 테스트 및 배포

📚 시리즈 네비게이션


“배포는 시작일 뿐입니다!” 🚀

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.