env 파일은 왜 숨겨야 할까?
팀 프로젝트를 진행하다 보면 .env 파일을 만들고, .gitignore에 추가하는 것이 거의 필수처럼 여겨진다. 하지만 막상 왜 .env 파일을 숨겨야 하는지, 환경변수는 어떻게 관리해야 하는지를 제대로 이해하지 못하고 있었다.
새로운 프로젝트를 시작하기 앞서 환경변수 관리에 대해 한 번 정리해보려고 한다.
💡 실무에서는 ?
현업에서는 .env 파일을 아예 사용하지 않고,
AWS Secret Manager와 같은 중앙 시크릿 저장소에서 실행 시점에 환경변수를 주입하는 방식도 사용한다고 한다.
🔍 Further Reading
📘 Official Docs
환경변수란?
환경변수(Environment Variable)는 애플리케이션이 실행되는 환경에 따라 달라질 수 있는 값을 저장하는 변수다.
예를 들어,
- 개발 환경에서는 로컬 API 서버
- 운영 환경에서는 실제 서비스 API 서버
처럼 같은 코드라도 환경에 따라 다른 값을 사용해야 할 때가 많다.
이런 값들을 코드 안에 직접 작성하지 않고, 환경변수로 분리해 관리한다.
env 파일은 무엇을 담고 있을까?
env 파일은 코드가 아니라 설정값을 담는 파일이다.
환경에 따라 달라질 수 있는 값들을 코드 밖으로 분리하기 위해 사용한다.
예를 들면 다음과 같다.
VITE_API_BASE_URL=https://api.example.com
VITE_API_KEY=abcd1234
NODE_ENV=development
# WebSocket
VITE_WS_BASE_URL=wss://api.example.com보통 이런 정보들이 들어간다.
- API 서버 주소
- 외부 서비스 연동 정보
- 데이터베이스 접속 정보
- 인증 관련 토큰
이 중 상당수는 외부에 노출되면 문제가 되는 값들이다.
왜 env 파일은 숨겨야 할까?
1. 민감한 정보 노출 방지
.env 파일에는 다음과 같은 민감한 정보들이 포함될 수 있다.
- API 키 / 시크릿 키
- 데이터베이스 접속 정보
- JWT 시크릿 키
- 외부 서비스 인증 토큰
이런 정보가 GitHub 같은 공개 저장소에 올라가면
누구나 접근할 수 있게 되고, 실제로 다음과 같은 문제가 발생할 수 있다.
- 금전적 피해: API 키를 이용한 무단 사용
- 데이터 유출: DB 접근 정보 노출
- 서비스 악용: 인증 키를 이용한 비정상적인 요청
이건 단순한 실수가 아니라 서비스 전체에 영향을 줄 수 있는 보안 이슈다.
env 파일을 안전하게 관리하는 방법
1. .gitignore에 추가하기
가장 기본적인 방법은 .env 파일을 Git에서 추적하지 않도록 설정하는 것이다.
# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local이렇게 하면 실수로 커밋되는 것을 막을 수 있다.
2. .env.example 파일 제공하기
팀 프로젝트나 오픈소스 프로젝트에서는 .env.example 파일을 함께 제공하는 것이 일반적이라고 한다.
# ==========================
# Frontend Environment
# (exposed to client)
# ==========================
# API base URL
# ex) http://localhost:8000
# ex) https://api.service.com
VITE_API_BASE_URL=
# Feature flags
VITE_ENABLE_ANALYTICS=false
VITE_ENABLE_DEBUG_MODE=false
# ==========================
# Backend Environment
# (server only - DO NOT expose)
# ==========================
# Authentication
JWT_SECRET=
JWT_EXPIRES_IN=7d
# Database
DATABASE_URL=즉, .env.example는 단순한 샘플 파일이 아니라 환경변수의 역할과 책임을 설명하는 설정 명세서에 가깝다.
3. 환경별로 env 파일 분리하기
환경마다 설정이 다른 경우, env 파일을 분리해 관리할 수 있다.
.env.development→ 개발 환경.env.test→ 테스트 환경.env.production→ 운영 환경
이렇게 하면, 환경 전환 시 코드 수정 없이 설정만 바꿀 수 있다.
Vite 환경변수 사용 시 주의할 점
Vite를 사용하는 경우, 환경변수 이름은 반드시 VITE_ 접두사를 사용해야 한다.
VITE_API_URL=https://api.example.com
VITE_API_KEY=abcd1234// 사용 예시
const apiUrl = import.meta.env.VITE_API_URL;
const apiKey = import.meta.env.VITE_API_KEY;VITE_ 접두사는 왜 필요할까?
Vite에서는 모든 환경변수를 기본적으로 차단하고, VITE_ 접두사가 붙은 값만 브라우저에 노출한다. 이는 프론트엔드에서 실수로 민감한 정보를 노출하는 사고를 막기 위한 의도적인 설계다.
즉, VITE_는 보안 기능이 아니라 "이 값은 공개해도 된다"는 명시적인 선언이다.
환경변수는 왜 환경마다 나눌까?
프로젝트는 보통 하나의 환경에서만 실행되지 않는다.
- 개발 환경 (dev)
- 테스트 / 스테이징 환경 (staging)
- 운영 환경 (production)
예를 들어 API 주소만 보더라도:
# 개발
VITE_API_URL=http://localhost:3000
# 운영
VITE_API_URL=https://api.service.com이렇게 달라진다.
만약 이런 값을 코드에 직접 작성해두면 환경이 바뀔 때마다 코드를 수정해야 하고, 실수할 가능성도 커진다.
환경변수를 사용하면 코드는 그대로 두고 설정만 변경할 수 있다.
프론트엔드에서 env를 사용할 때 꼭 알아야 할 점
여기서 많이 헷갈리는 부분이 있다. 프론트엔드의 env 파일은 보안 수단이 아니다.
Vite, Next.js 같은 프로젝트에서는 환경변수가 빌드 시점에 자바스크립트 코드에 포함된다.
즉,
- 브라우저로 전달되고
- 개발자 도구로 확인 가능하다.
그래서 프론트엔드 env에는 결제 시크릿 키나 관리자 토큰 같은 진짜 비밀 값을 넣으면 안 된다.
프론트엔드 env에는 보통 이런 값만 둔다.
- API base URL
- 공개 가능한 설정 값
- feature flag
민감한 정보는 반드시 서버에서 관리해야 한다.
프로덕션 환경에서는 어떻게 관리할까?
1. Vercel
Vercel 대시보드의 Project Settings에서 환경별(Environment, Preview, Development)로 환경변수를 설정할 수 있다.
2. Netlify
Netlify도 Site settings → Build & deploy → Environment에서 관리할 수 있다.
3. GitHub Actions
CI/CD 환경에서는 Repository Secrets를 사용해 환경변수를 안전하게 관리한다.
실수로 env 파일을 커밋했다면?
상상하기 싫지만, 만약 .env 파일을 실수로 커밋하고 푸시했다면 다음 순서로 대응해야 한다.
- 즉시 키 재발급
노출된 API 키나 시크릿은 바로 폐기하고 새로 발급한다.
- 즉시 키 재발급
- Git 히스토리에서 완전 제거
단순 삭제만으로는 부족하므로BFG Repo-Cleaner같은 도구를 사용해 히스토리에서 제거한다.
- Git 히스토리에서 완전 제거
- 팀원에게 공유
저장소를 새로 클론받도록 안내한다.
- 팀원에게 공유
bfg --delete-files .env
git reflog expire --expire=now --all
git gc --prune=now --aggressive환경변수 관리는 단순히 코드를 깔끔하게 유지하는 문제가 아니다.
보안과 직결된 기본적인 설계 선택에 가깝다. 처음에는 번거롭게 느껴질 수 있지만, 배포와 협업을 경험할수록 env 파일이 왜 중요한지 자연스럽게 체감하게 된다.