Vercel에서 환경별 설정 분리
Vercel에서 개발, 스테이징, 프로덕션 환경을 분리하여 설정하는 방법을 알아봅니다.
Vercel에서 환경별 설정 분리
Introduction
개발, 스테이징, 프로덕션 환경을 효과적으로 분리하면 배포 안정性和 개발 효율성을 높일 수 있습니다. 이 글에서는 Vercel에서 환경별 설정을 분리하는 방법을 알아보겠습니다.
Environment
- Vercel 프로젝트 (Next.js 14+)
- GitHub/GitLab
- 환경 변수 관리
- 브랜치 전략
Problem
환경 변수가 혼재되어 있을 때 발생하는 문제:
// .env.local (로컬 개발)
DATABASE_URL=postgresql://localhost:5432/dev
API_KEY=dev-key-12345
// Vercel 프로덕션
DATABASE_URL=postgresql://prod-host:5432/prod
API_KEY=prod-key-67890
// 실수로 개발 키가 프로덕션에 배포되는 경우 발생Analysis
Vercel 환경 분리 구조:
- Development: 로컬 개발 환경
- Preview: PR 시 자동 생성되는 프리뷰 환경
- Production: 메인 브랜치 배포
Solution
1. Vercel 대시보드에서 환경 변수 설정
# 환경 변수 추가
vercel env add DATABASE_URL production
vercel env add DATABASE_URL preview
vercel env add DATABASE_URL development
# 환경 변수 목록 확인
vercel env ls2. vercel.json 환경 설정
{
"env": {
"DATABASE_URL": "@database-url",
"API_KEY": "@api-key"
},
"build": {
"env": {
"NEXT_PUBLIC_API_URL": "@api-url"
}
}
}3. 환경별 설정 파일
// config/environments.js
const environments = {
development: {
apiUrl: 'http://localhost:3000',
databaseUrl: process.env.DATABASE_URL,
debug: true,
},
preview: {
apiUrl: `https://${process.env.VERCEL_URL}`,
databaseUrl: process.env.DATABASE_URL,
debug: true,
},
production: {
apiUrl: 'https://your-app.vercel.app',
databaseUrl: process.env.DATABASE_URL,
debug: false,
},
};
export function getConfig() {
const env = process.env.VERCEL_ENV || 'development';
return environments[env] || environments.development;
}4. 브랜치 전략에 따른 배포
# .github/workflows/vercel-deploy.yml
name: Deploy to Vercel
on:
push:
branches: [main, develop, 'feature/*']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: ${{ github.ref == 'refs/heads/main' && '--prod' || '' }}5. 환경 변수 검증
// lib/env-validation.js
const requiredEnvVars = [
'DATABASE_URL',
'API_KEY',
'NEXTAUTH_SECRET',
];
export function validateEnvironment() {
const missing = requiredEnvVars.filter(
(envVar) => !process.env[envVar]
);
if (missing.length > 0) {
console.error('Missing environment variables:', missing);
throw new Error(`Missing required env vars: ${missing.join(', ')}`);
}
// 환경별 검증
const env = process.env.VERCEL_ENV || 'development';
if (env === 'production') {
if (process.env.DEBUG === 'true') {
console.warn('DEBUG mode is enabled in production');
}
}
return true;
}6. 프리뷰 환경 설정
// app/api/preview-info/route.js
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({
environment: process.env.VERCEL_ENV,
url: process.env.VERCEL_URL,
gitBranch: process.env.VERCEL_GIT_COMMIT_REF,
gitCommit: process.env.VERCEL_GIT_COMMIT_SHA,
});
}7. 환경별 데이터베이스 연결
// lib/database.js
import { PrismaClient } from '@prisma/client';
const databaseConfigs = {
development: {
log: ['query'],
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
},
preview: {
log: ['error'],
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
},
production: {
log: ['error'],
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
},
};
const env = process.env.VERCEL_ENV || 'development';
export const prisma = new PrismaClient(databaseConfigs[env]);8. CI/CD 환경 분리
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
env:
DATABASE_URL: postgresql://localhost:5432/test
- name: Run lint
run: npm run lintLessons Learned
- 일관된 명명 규칙: 환경 변수명을 일관되게 유지하면 관리가 용이합니다.
- 보안 고려: 프로덕션 키가 개발 환경에 노출되지 않도록 주의해야 합니다.
- 자동화: CI/CD 파이프라인에서 환경 변수를 자동으로 설정하면 실수를 줄일 수 있습니다.
- 문서화: 환경 변수 목록과 용도를 문서화하면 팀원들의 이해를 돕습니다.
- 모니터링: 환경별 설정이 올바르게 적용되는지 주기적으로 확인해야 합니다.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.