환경 변수와 비밀값 관리: .env를 커밋하면 안 되는 이유
API 키, DB 비밀번호, 토큰. 이런 값을 코드에 하드코딩하면 깃 히스토리에 영원히 박힙니다. 설정을 환경 변수로 분리하는 습관이 필요합니다.
왜 환경으로 분리하나
같은 코드가 로컬·스테이징·운영에서 다른 값으로 동작해야 합니다(다른 DB, 다른 키). 코드는 그대로 두고 환경만 바꾸는 게 핵심입니다(12-Factor App의 원칙).
DATABASE_URL=postgres://localhost/dev # 로컬
DATABASE_URL=postgres://prod-host/app # 운영
.env는 커밋하지 않는다
.env에는 진짜 비밀값이 들어갑니다. 반드시 .gitignore에 넣으세요.
# .gitignore
.env
.env.local
.env*.local
대신 키 이름만 적힌 .env.example을 커밋해 팀이 무엇을 채워야 하는지 공유합니다.
# .env.example (값은 비워둠 → 안전)
DATABASE_URL=
API_KEY=
프론트로 새는 값 조심: NEXT_PUBLIC_
Next.js에서 NEXT_PUBLIC_ 접두사가 붙은 변수는 브라우저 번들에 그대로 포함됩니다. 즉 누구나 볼 수 있습니다.
NEXT_PUBLIC_GA_ID=G-XXXX # OK: 어차피 공개되는 값
SECRET_API_KEY=... # 접두사 없음 → 서버에서만 접근 가능
비밀 키에는 절대 NEXT_PUBLIC_를 붙이지 마세요. 결제·DB·관리자 키가 클라이언트로 새면 끝장입니다.
운영에선 플랫폼 비밀 저장소를 쓴다
배포 환경(Vercel, Cloud 등)에서는 .env 파일 대신 대시보드의 환경 변수/시크릿 기능에 넣습니다. 파일이 서버에 남지 않아 더 안전합니다.
키가 유출됐다면
- 즉시 해당 키를 폐기(rotate) — 깃에서 지워도 히스토리에 남아 있으므로 키 자체를 무효화
- 새 키 발급 후 환경 변수 교체
- 깃 히스토리 정리가 필요하면
git filter-repo등으로 제거(이미 푸시됐다면 노출됐다고 가정)
마무리 체크리스트
- 비밀값은 코드 말고 환경 변수로
.env는.gitignore, 공유는.env.example- 클라이언트 노출 접두사(
NEXT_PUBLIC_)에 비밀값 금지 - 유출 시 키 폐기가 1순위
"이 값이 깃에 올라가도 괜찮은가?"를 매번 자문하면 사고의 대부분을 막을 수 있습니다.
함께 보면 좋은 글
Docker 입문: 이미지와 컨테이너 개념부터 첫 실행까지
이미지와 컨테이너의 차이가 헷갈리는 입문자를 위한 가이드입니다. Dockerfile 작성, build/run/exec 명령어, 그리고 실무에서 자주 쓰는 명령을 실제 예제로 익혀보세요.
CORS 에러, 도대체 왜 나는 걸까: 원리와 해결
브라우저의 동일 출처 정책, preflight(OPTIONS) 요청, Access-Control-Allow-* 헤더의 역할을 이해하면 CORS 에러는 더 이상 미스터리가 아닙니다.
REST API 설계 원칙: 실무에서 욕먹지 않는 7가지 규칙
URL에 동사를 넣고, 200으로 에러를 내보내는 잘못된 API는 이제 그만. 리소스 명명, HTTP 메서드, 상태 코드, 버저닝까지 실무 표준에 맞춰 REST API를 설계하는 법을 정리했습니다.