Ch 06. 환경변수와 런타임 설정 관리
API 키, 데이터베이스 URL, JWT 시크릿처럼 외부에 노출되어서는 안 되는 값들이 있습니다. 이런 값을 코드에 직접 작성하면 Git에 올라가는 순간 누구에게나 공개됩니다. Nuxt는 이를 안전하게 관리하기 위한 runtimeConfig 시스템을 제공합니다.
.env와 runtimeConfig의 관계
세 가지 방식을 구분해서 이해하는 것이 중요합니다.
| 방식 | 노출 범위 | 용도 |
|---|---|---|
.env |
서버 전용 (Git 제외) | 실제 시크릿 값 저장 |
runtimeConfig (최상위) |
서버에서만 접근 가능 | 서버 전용 설정 |
runtimeConfig.public |
클라이언트에도 노출 | 공개해도 무방한 설정 |
.env 파일의 값이 runtimeConfig의 기본값을 덮어씁니다. 코드에는 빈 문자열로 선언해 두고, .env에 실제 값을 넣는 방식으로 사용합니다.
nuxt.config.ts 설정
export default defineNuxtConfig({ runtimeConfig: { jwtSecret: '', // 서버 전용 databaseUrl: '', // 서버 전용 public: { apiBase: '/api', // 클라이언트 노출 가능 appName: '내 앱' } }})
public 안에 있는 값은 클라이언트 번들에도 포함됩니다. API 주소나 앱 이름처럼 공개해도 무방한 값만 여기에 넣습니다. jwtSecret처럼 절대 노출되어서는 안 되는 값은 최상위에 둡니다.
.env 파일 작성
NUXT_JWT_SECRET=your-secret-key
NUXT_DATABASE_URL=file:./dev.db
NUXT_PUBLIC_API_BASE=/api
Nuxt는 환경변수 이름 규칙을 자동으로 매핑합니다. NUXT_ 접두어로 시작하는 값은 runtimeConfig 최상위에, NUXT_PUBLIC_ 접두어는 runtimeConfig.public에 자동으로 주입됩니다.
.env 파일은 반드시 .gitignore에 추가해야 합니다.
# .gitignore
.env
.env.*
!.env.example
대신 .env.example 파일에 빈 값으로 키만 적어 둬서 팀원들이 어떤 값이 필요한지 알 수 있게 합니다.
서버와 클라이언트에서 사용하기
서버 핸들러에서는 useRuntimeConfig(event)를 호출합니다. event를 전달하면 요청 컨텍스트와 함께 설정을 가져옵니다.
// server/api/example.tsexport default defineEventHandler((event) => { const config = useRuntimeConfig(event) const secret = config.jwtSecret // 서버 전용 값 접근 가능 const apiBase = config.public.apiBase // 공개 값 return { apiBase }})
클라이언트 측 컴포넌트에서는 event 없이 호출합니다. 이 경우 public 항목만 접근할 수 있습니다.
// composables/useApi.tsconst config = useRuntimeConfig()const apiBase = config.public.apiBase // '/api'
클라이언트에서 config.jwtSecret처럼 비공개 값에 접근하려 하면 undefined가 반환됩니다. 실수로 노출되는 사고를 예방하기 위한 설계입니다.
환경별 .env 파일 분리
개발과 운영 환경의 설정이 다를 때는 파일을 분리합니다.
.env.development # npm run dev 시 사용
.env.production # npm run build 시 사용
.env # 공통 기본값
환경별로 데이터베이스 URL, API 주소, 로깅 수준 등을 다르게 설정할 수 있습니다.
시크릿은 코드 밖에, 공개 설정은 코드 안에. runtimeConfig는 이 원칙을 구조적으로 지킬 수 있게 해 줍니다. 팀 프로젝트에서도 .env.example만 잘 관리하면 새 팀원이 환경 설정에 어려움 없이 합류할 수 있습니다.