DevOps
환경 변수 관리 가이드
개발, 스테이징, 프로덕션 환경별로 설정을 관리하는 방법을 알아봅니다.
환경 변수는 코드와 설정을 분리하는 방법입니다. API 키, 데이터베이스 URL 등 환경마다 다른 값을 안전하게 관리할 수 있습니다.
.env 파일 사용
# .env.local (개발용, git에 포함 안 됨)
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=dev_api_key_123
NEXT_PUBLIC_API_URL=http://localhost:3000/api
# .env.production (프로덕션용)
DATABASE_URL=postgresql://prod-db.example.com:5432/mydb
API_KEY=prod_api_key_456
NEXT_PUBLIC_API_URL=https://api.example.com
Next.js에서 환경 변수
// 서버에서만 사용 (API 키 등)
const apiKey = process.env.API_KEY;
// 클라이언트에서도 사용 (NEXT_PUBLIC_ 접두사)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
NEXT_PUBLIC_ 접두사가 없으면 서버에서만 접근 가능합니다. 민감한 정보는 절대 NEXT_PUBLIC_을 붙이지 않습니다.
환경 변수 검증
// env.ts
const requiredEnvVars = [
'DATABASE_URL',
'API_KEY',
'JWT_SECRET',
] as const;
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
throw new Error(`Missing required environment variable: ${envVar}`);
}
}
export const env = {
databaseUrl: process.env.DATABASE_URL!,
apiKey: process.env.API_KEY!,
jwtSecret: process.env.JWT_SECRET!,
nodeEnv: process.env.NODE_ENV || 'development',
isProduction: process.env.NODE_ENV === 'production',
};
Zod로 타입 안전하게
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
API_KEY: z.string().min(10),
JWT_SECRET: z.string().min(32),
PORT: z.coerce.number().default(3000),
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
});
export const env = envSchema.parse(process.env);
.env 파일 관리
# .gitignore
.env
.env.local
.env.*.local
# git에 포함해도 되는 파일
# .env.example (샘플, 실제 값 없음)
.env.example 작성
# .env.example
# 이 파일을 복사해서 .env.local로 저장하세요
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
# API Keys (발급받아서 입력)
API_KEY=your_api_key_here
# Public (클라이언트에서 접근 가능)
NEXT_PUBLIC_API_URL=http://localhost:3000/api
환경별 설정
개발 (development)
- 로컬 데이터베이스
- 디버그 로깅 활성화
- 테스트 API 키
스테이징 (staging)
- 테스트 서버
- 프로덕션과 유사한 환경
- 제한된 접근
프로덕션 (production)
- 실제 서버
- 최소한의 로깅
- 실제 API 키
비밀 관리 서비스
Vercel Environment Variables
# CLI로 설정
vercel env add DATABASE_URL
# 환경별로 다른 값 설정 가능
# - Development
# - Preview
# - Production
AWS Secrets Manager
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager({ region: 'ap-northeast-2' });
async function getSecret(secretId: string) {
const response = await client.getSecretValue({ SecretId: secretId });
return JSON.parse(response.SecretString || '{}');
}
보안 주의사항
[ ] .env 파일 절대 git에 커밋하지 않기
[ ] 클라이언트에 민감한 정보 노출하지 않기
[ ] API 키는 주기적으로 교체
[ ] 로그에 환경 변수 출력하지 않기
[ ] .env.example에 실제 값 넣지 않기
흔한 실수
// 나쁜 예: 로그에 출력
console.log('API Key:', process.env.API_KEY);
// 나쁜 예: 클라이언트에서 접근 시도
const apiKey = process.env.API_KEY; // undefined (서버 전용)
// 나쁜 예: 하드코딩
const apiKey = 'sk_live_abc123'; // 절대 금지!
마무리
환경 변수 관리는 보안과 직결됩니다. 민감한 정보는 환경 변수로 관리하고, 절대 코드에 하드코딩하지 않습니다.
팀에서 작업할 때는 .env.example을 잘 관리해서 새로운 팀원이 쉽게 환경을 설정할 수 있도록 합니다.