본문 바로가기
web

[3편] 환경변수 관리와 Firebase 멀티 프로젝트 운영 팁

by kkong93 2026. 3. 18.

1편에서 프로젝트 세팅, 2편에서 배포+트러블슈팅을 다뤘다. 이번 편에서는 실제로 운영하면서 필요한 환경변수 관리 방법이랑, Firebase 프로젝트를 2개 이상 쓸 때 주의점을 정리한다.

 

1편 ->

2026.03.18 - [web] - [1편] Next.js + Firebase 프로젝트 생성부터 초기 설정까지 (Windows 11)

2편 ->

2026.03.18 - [web] - [2편] Firebase Hosting 배포하기 + Cloud Build 오류 트러블슈팅 (Windows 11)


1. 환경변수 종류 정리

Next.js + Firebase 프로젝트에서 환경변수는 크게 3군데서 관리된다:

(1) .env.local — 로컬 개발용

# .env.local
NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSyXXXXXXXX
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=my-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=my-project
  • NEXT_PUBLIC_ 접두사: 브라우저에서 접근 가능 (클라이언트 사이드)
  • 접두사 없으면: 서버에서만 접근 가능 (API 키 같은 민감 정보)
  • Git에 올리면 안 됨

(2) Firebase Functions 환경변수 — 서버 사이드

Firebase Functions에서 쓰는 환경변수는 별도로 설정한다:

# Firebase Functions 환경변수 설정
firebase functions:config:set service.api_key="my-secret-key"

# 확인
firebase functions:config:get

또는 최신 방식 (2nd gen Functions):

# .env 파일을 functions/ 폴더에 생성
# functions/.env
API_KEY=my-secret-key
DATABASE_URL=https://my-db.firebaseio.com

(3) Firebase Console 환경변수

Firebase Console > 프로젝트 설정에서 웹 앱 구성을 확인할 수 있다. 여기 있는 apiKey, authDomain 같은 값들이 .env.local에 넣는 값들이다.


2. 환경변수 파일 구조

실제로 이렇게 관리하면 편하다:

my-project/
├── .env.local              ← 로컬 개발용 (Git 제외)
├── .env.example            ← 팀원용 템플릿 (Git 포함, 값은 비움)
└── functions/
    ├── .env                ← Functions 환경변수 (Git 제외)
    └── .env.example        ← Functions 템플릿 (Git 포함)

.env.example 파일

이건 Git에 올려도 된다. 값은 비워두고 키 이름만 적어놓는 것:

# .env.example (Git에 올리는 용)
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=

새로 프로젝트 클론한 사람은 이 파일을 .env.local로 복사해서 값만 채우면 된다:

cp .env.example .env.local

Android 개발자를 위한 비유: 이건 local.properties를 .gitignore에 넣고, local.properties.example을 올려두는 것과 같은 패턴이다.


3. NEXT_PUBLIC_ 접두사의 함정

이거 처음에 좀 헷갈렸다. Next.js에서 환경변수 접두사에 따라 접근 범위가 달라진다:

# 브라우저 + 서버 둘 다 접근 가능
NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSy...

# 서버에서만 접근 가능 (브라우저에서 undefined)
FIREBASE_ADMIN_KEY={"type": "service_account", ...}

Firebase 웹 SDK 설정값(apiKey, authDomain 등)은 어차피 브라우저에서 쓰는 거니까 NEXT_PUBLIC_을 붙여야 한다. 근데 Firebase Admin SDK 키 같은 건 절대 NEXT_PUBLIC_을 붙이면 안 된다. 브라우저에 노출되면 보안 사고 난다.

정리하면:

환경변수 접두사 이유

Firebase 웹 SDK 설정 NEXT_PUBLIC_ 필요 브라우저에서 Firebase 초기화할 때 씀
Firebase Admin SDK 키 접두사 없음 서버에서만 써야 함
외부 API 키 접두사 없음 서버에서만 호출해야 안전

4. Firebase 프로젝트 2개 운영

나는 .firebaserc에 프로젝트가 2개 등록되어 있다:

{
  "projects": {
    "default": "project-dev",
    "production": "project-prod"
  }
}

전환 방법

firebase use default      # 개발용 프로젝트
firebase use production   # 프로덕션 프로젝트

# 현재 어떤 프로젝트인지 확인
firebase use

주의할 점

배포 전에 반드시 firebase use로 확인하는 습관을 들여야 한다. 나는 한 번 개발용 프로젝트에서 작업하다가 그대로 firebase deploy 해버린 적이 있다. 프로덕션에 배포하려고 했는데 개발용에 배포된 것...

이걸 방지하려면 배포 스크립트를 만들어두는 게 좋다:

// package.json의 scripts에 추가
{
  "scripts": {
    "deploy:dev": "firebase use default && firebase deploy --only hosting",
    "deploy:prod": "firebase use production && firebase deploy --only hosting"
  }
}

이렇게 하면:

npm run deploy:dev    # 개발 프로젝트에 배포
npm run deploy:prod   # 프로덕션 프로젝트에 배포

실수할 확률이 줄어든다.

환경변수도 프로젝트별로 분리

프로젝트가 2개면 환경변수도 다를 수 있다. 이럴 때:

# .env.local → 개발용 (기본)
NEXT_PUBLIC_FIREBASE_PROJECT_ID=project-dev

# .env.production.local → 프로덕션용
NEXT_PUBLIC_FIREBASE_PROJECT_ID=project-prod

Next.js는 next build 할 때 .env.production.local을 자동으로 읽는다. 그래서 로컬 개발(next dev)할 때는 .env.local이 적용되고, 빌드할 때는 .env.production.local이 적용된다.


5. 실수했을 때 대처법

잘못된 프로젝트에 배포했을 때

Firebase Hosting은 이전 배포로 롤백할 수 있다:

  1. Firebase Console > Hosting 접속
  2. 배포 이력에서 이전 버전 선택
  3. "롤백" 클릭

또는 CLI에서:

firebase hosting:rollback

환경변수를 잘못 커밋했을 때

.env.local을 실수로 Git에 올렸으면:

# 1. .gitignore에 추가 (이미 되어있어야 하지만)
echo .env.local >> .gitignore

# 2. Git 추적에서 제거 (파일은 삭제 안 됨)
git rm --cached .env.local
git commit -m "Remove .env.local from tracking"
git push

근데 이미 올라간 커밋에 API 키가 있으면, Firebase Console에서 해당 API 키를 재생성하는 게 안전하다. Git 히스토리에 남아있으니까.


6. 최종 .gitignore (완성본)

1편에서 다뤘던 걸 다시 한번 정리하면, 최종 .gitignore:

# === 의존성 ===
node_modules/

# === 빌드 결과물 ===
.next/
out/
dist/

# === 환경변수 (절대 올리지 마) ===
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# === Firebase ===
.firebase/

# === Firebase 키 파일 ===
serviceAccountKey.json
*-firebase-adminsdk-*.json

# === Functions 환경변수 ===
functions/.env
functions/.env.local

# === OS ===
.DS_Store
Thumbs.db

# === IDE ===
.vscode/settings.json
.idea/
*.swp
*.swo

# === 디버그 로그 ===
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# === TypeScript ===
*.tsbuildinfo
next-env.d.ts

7. 전체 시리즈 정리

1편에서 다룬 것

  • Node.js / Firebase CLI 설치
  • Next.js 프로젝트 생성 (create-next-app)
  • npm install 과 package-lock.json 의 중요성
  • Firebase 초기화 (firebase init)
  • .firebaserc와 firebase.json 설정
  • 환경변수 기본 설정 (.env.local)
  • .gitignore 설정
  • 프로젝트 폴더 구조

2편에서 다룬 것

  • 배포 전 로컬 빌드 확인
  • Firebase 프로젝트 전환 (firebase use)
  • firebase deploy --only hosting 배포
  • Cloud Build에서 @opentelemetry/api@1.9.0 누락 오류
  • npm ci vs npm install 차이
  • 해결법: opentelemetry 명시 설치 → node_modules/lock 전체 초기화 → 새로 설치 → 배포

3편에서 다룬 것 (이 글)

  • 환경변수 3가지 종류 (.env.local, Functions 환경변수, Firebase Console)
  • NEXT_PUBLIC_ 접두사 규칙
  • .env.example 패턴
  • Firebase 멀티 프로젝트 운영 방법
  • 실수 대처법 (롤백, API 키 노출 시)
  • 최종 .gitignore

마무리

안드로이드 개발자가 웹+서버까지 같이 하게 되면, 처음에는 낯선 것투성이다. npm, Node.js, 환경변수 관리 방식... 전부 Gradle이랑 Android Studio 세계와는 다르다.

근데 한 번 세팅해놓으면 구조 자체는 비슷하다. package.json은 build.gradle이고, node_modules는 .gradle 캐시고, .env.local은 local.properties다. 이렇게 1:1로 대응시켜서 이해하면 훨씬 빠르게 적응할 수 있다.

그리고 배포 오류의 90%는 환경 차이 에서 온다. 로컬이랑 CI 환경이 다르기 때문에, package-lock.json 관리가 진짜 중요하다. 이번에 opentelemetry 삽질하면서 뼈저리게 느꼈다.

비슷한 오류 겪고 있는 분들한테 도움이 됐으면 좋겠다..

 

반응형

댓글