process.env는 셸이 Node.js 프로그램에 넘긴 환경 변수마다 속성이 하나씩 있는 객체입니다. process.env.PORT, process.env.DATABASE_URL처럼 읽습니다. 설정되지 않은 변수는 undefined이고, 설정된 변수는 항상 문자열입니다. 시작할 때 한 번 읽고, 기본값을 주고, 필요한 타입으로 바꾸세요.
shop on port 8080 in eu-west가 출력되었습니다(REGION은 설정된 적이 없어서 기본값이 쓰였습니다). 이어서 string number가 나왔는데, 변수는 Number()로 바꾸기 전까지 텍스트입니다. 처음 두 대입을 지우고 다시 실행하면 모든 기본값을 볼 수 있습니다.
셸에서 환경 변수 설정하기
변수는 Node.js를 시작한 곳에서 옵니다. 터미널에서는 이렇게 합니다.
// macOS and Linux: for one command
PORT=8080 NODE_ENV=production node app.js
// macOS and Linux: for the rest of the terminal session
export PORT=8080
// Windows PowerShell
$env:PORT = "8080"; node app.js
// Windows cmd.exe
set PORT=8080
node app.js
호스팅 플랫폼(Heroku, Render, Vercel, Docker, Kubernetes)에는 같은 일을 하는 설정 화면이나 파일이 있고, 코드에서 읽는 방법은 같습니다.
모든 값은 문자열입니다
process.env 버그는 대부분 여기서 나옵니다. 'false'와 '0'은 비어 있지 않은 문자열이라서 truthy입니다.
단순한 검사는 false로 설정한 변수에도 debug is ON을 출력했습니다. 그러니 기대하는 문자열과 정확히 비교하세요. 숫자라면 Number(process.env.X)가 값이 없을 때 NaN이 되므로, 첫 예제에서 ??로 한 것처럼 변환하기 전에 기본값을 적용하세요.
NODE_ENV
NODE_ENV는 Node.js 기능이 아니라 관례입니다. Node.js는 이 값을 설정하지 않고, 라이브러리가 읽습니다. 예를 들어 Express는 이 값이 production이면 에러 페이지에서 스택 트레이스를 숨기고, 많은 도구가 개발용 검사를 건너뜁니다.
mode: production과 verbose logs: false가 출력되었습니다. 'production'을 'development'로 바꾸면 두 번째 줄이 뒤집힙니다. 라이브러리는 정확히 이 단어들을 확인하므로 production, development, test만 쓰세요.
.env 파일: --env-file과 dotenv
node 앞에 모든 변수를 매번 타이핑하는 건 금방 지칩니다. .env 파일을 쓰면 프로젝트 폴더에 한 줄에 하나씩 둘 수 있습니다.
// .env
PORT=8080
DATABASE_URL=postgres://localhost/shop
API_KEY=dev-key-123
Node.js 20.6 이후는 패키지 없이 플래그 하나로 읽습니다.
node --env-file=.env app.js
이전 버전이거나 이쪽이 더 편하다면 dotenv 패키지를 설치하고(npm install dotenv), 진입 파일 맨 위, process.env를 읽는 코드보다 앞에서 불러오세요.
require('dotenv').config(); // copies .env into process.env
console.log(process.env.PORT); // 8080
어느 쪽도 셸에서 이미 설정된 변수는 덮어쓰지 않으므로, 운영 환경의 설정이 파일보다 우선합니다.
빠진 변수는 일찍 실패시키기
데이터베이스 URL이 없다면 한 시간 뒤 첫 요청에서 죽을 것이 아니라, 시작할 때 분명한 메시지와 함께 멈춰야 합니다.
Missing environment variables: API_KEY가 출력되었습니다. 맨 위에 process.env.API_KEY = 'test';를 추가하면 Config OK가 출력됩니다. 실제 프로그램에서는 메시지 뒤에 process.exit(1)을 쓰세요. 배포 스크립트나 컨테이너 플랫폼은 0이 아닌 종료 코드를 보고 시작이 실패했다는 것을 압니다.
비밀 값은 절대 커밋하지 마세요
.env는 만든 날 바로 .gitignore에 넣으세요. 대신 변수 이름과 가짜 값을 적은 .env.example을 커밋해 두면 다른 사람도 무엇을 설정해야 할지 압니다. 한 번이라도 저장소에 푸시된 키는 나중에 커밋을 지우더라도 유출된 것으로 보고 교체해야 합니다.
자주 묻는 질문
process.env.MY_VAR가 undefined인 이유는 뭔가요?
Node.js를 시작한 셸에서 변수를 설정하지 않았거나, 다른 터미널에서 설정했기 때문입니다. .env 파일도 자동으로 읽히지 않습니다. 값을 읽기 전에 --env-file=.env로 Node.js를 시작하거나 dotenv로 불러오세요.
실행 중에 process.env를 바꿀 수 있나요?
네. process.env.X = 'value'로 대입하면 현재 프로세스와 그 뒤에 시작하는 자식 프로세스에서는 값이 바뀌지만, Node.js를 실행한 셸에는 절대 반영되지 않습니다. 대입한 값은 Node.js가 문자열로 바꿉니다.
환경 변수 이름은 대소문자를 구분하나요?
리눅스와 macOS에서는 구분합니다. PORT와 port는 서로 다른 변수입니다. 윈도우에서는 구분하지 않습니다. 밑줄을 쓴 대문자 이름으로 통일하면 이 문제는 생기지 않습니다.
브라우저에서 process.env를 읽을 수 있나요?
없습니다. 브라우저에는 환경 변수가 없습니다. Vite나 Next.js 같은 빌드 도구는 고른 변수를 빌드할 때 프론트엔드 코드에 복사하는데, 그 말은 그 값이 공개된다는 뜻이기도 합니다.