Node.js에서 환경 변수 다루기 (process.env)
여러 환경에 동일한 애플리케이션을 배포하려면 환경 변수(environment variable)라는 것을 사용해야하는데요.
이번 포스팅에서는 환경 변수에 대한 기본 개념을 설명드리고 Node.js에서는 어떻게 환경 변수에 접근하고 설정할 수 있는지에 대해서 알아보겠습니다.
환경 변수란?
먼저 환경 변수(environment variable)가 무엇인지 간단하게 개념부터 짚고 넘어가면 좋을 것 같아요.
일반적으로 우리는 코드 베이스는 하나만 관리하고, 개발, 테스트, 운영 등 여러 환경에 애플리케이션을 배포하는데요. 어느 환경에 배포하느냐에 따라서 다르게 설정되야하는 값들은 보통 운영 체제 수준에서 환경 변수를 통해 관리하게 됩니다.
대표적인 예로, 데이터베이스(DB) 설정을 들 수 있는데요. 운영 환경에서는 데이터 센터나 클라우드 인프라 상의 상용 DB를 사용하고, 개발 환경에서는 개발자의 PC 상에서 돌고 있는 로컬 DB를 사용하는 경우가 많죠?
뿐만 아니라, 데이터베이스의 비밀번호나 서드파티(3rd-party) 서비스의 API 키와 같이 민감한 인증 정보는 GitHub와 같은 코드 저장소(repository)에 올리면 상당히 위험할 수 있기 때문에 환경 변수로 저장해놓고 사용하는 것이 권장됩니다.
환경 변수 접근
Node.js에서는 보통 process.env
를 통해서 환경 변수에 접근하게 되는데요.
process
는 Node.js에 기본적으로 내장된 전역 객체여서 별도로 불러올(import) 필요없이 프로그램의 어디에서든지 사용할 수 있습니다.
일부 환경 변수들은 우리가 직접 설정해주지 않더라도 운영 체제 수준에서 이미 설정이 되어 있는데요. 예를 들어, 터미널(terminal)을 열고 Node.js 인터프리터를 실행하시면 어떤 환경 변수들이 이미 설정되어 있는지 간단하게 확인해볼 수 있습니다.
$ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.env.USER
'dale'
> process.env.HOME
'/Users/dale'
> process.env.LANG
'en_US.UTF-8'
> process.env.API_KEY
undefined
참고로 이 process
객체는 Node.js에서만 사용이 가능하며, 브라우저와 같은 다른 자바스크립트 실행 환경에서는 존재하지 않는 전역 객체이오니 주의바라겠습니다.
(마치 window
객체가 브라우저 실행 환경에만 사용할 수 있고, Node.js에서는 존재하지 않는 것과 비슷한 경우라고 보시면 될 것 같아요.)
환경 변수 설정
환경 변수는 운영 체제에 따라서 약간씩 상이한 방법으로 설정할 수 있는데요.
가장 간단한 방법은 프로그램을 실행할 때 node
명령어 앞에 환경 변수를 키=값
형태로 붙여주면 됩니다.
예를 들어, API_KEY
라는 환경 변수를 abc
로, DB_PASSWORD
라는 환경 변수를 1234
로 설정해보겠습니다.
$ API_KEY=abc DB_PASSWORD=1234 node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.env.API_KEY
'abc'
> process.env.DB_PASSWORD
'1234'
이렇게 프로그램 실행 시 설정해준 환경 변수는 해당 프로그램이 실행되는 동안에만 유효하며 프로그램이 종료하면 사라집니다. 그래서 다음과 같이 다시 Node.js 인터프리터를 실행하면 이 전에 실행할 때 명시했던 환경 변수를 얻을 수 없습니다.
$ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.env.API_KEY
undefined
운영 체제에서 제공하는 명령어를 이용해서도 환경 변수를 설정해줄 수 있는데요.
예를 들어, Unix 계열에서는 export
명령어, Windows 계열에서는 SET
명령어가 사용됩니다.
이러한 운영 체제의 명령어를 이용하여 환경 변수를 설정하면 터미널 창을 닫을 때까지 유지되는데요. 예를 들어, 저는 Unix 계열인 MacOS를 사용하기 때문에 다음과 같이 환경 변수를 설정해줄 수 있습니다.
$ export API_KEY=abc
$ export DB_PASSWORD=1234
$ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.env.API_KEY
'abc'
> process.env.DB_PASSWORD
'1234'
이렇게 프로그램이 실행하기 전에 터미널에서 설정한 환경 변수는 해당 프로그램을 종료하고 다시 실행하더라도 동일한 환경 변수 값을 얻을 수 있습니다.
$ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.env.API_KEY
'abc'
> process.env.DB_PASSWORD
'1234'
사실 process.env
는 가변 객체이기 때문에 받드시 이렇게 프로그램 실행 시점이나 실행 이전에 설정해줘야 하는 것은 아닙니다.
프로그램 내에서 얼마든지 새로운 환경 변수를 설정하거나 기존에 설정된 환경 변수의 값을 자유롭게 갱신 또는 제거할 수 있습니다.
$ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.env.API_KEY = "abc"
'abc'
> process.env.API_KEY
'abc'
> process.env.API_KEY = "def"
'def'
> process.env.API_KEY
'def'
> delete process.env.API_KEY
true
> process.env.API_KEY
undefined
프로그램에서 활용
어떤 방법으로 환경 변수를 설정하든 이러한 환경 변수들은 결국 프로그램에서 활용이 될 때 의미가 있겠죠?
간단한 실습을 위해서 자바스크립트 파일을 하나 생성하고, 그 안에 다음과 같이 환경 변수를 읽어서 콘솔에 출력하는 코드를 작성해보겠습니다.
const { API_KEY, DB_PASSWORD } = process.env;
console.log('API_KEY:', API_KEY);
console.log('DB_PASSWORD:', DB_PASSWORD);
이제 새로운 터미널을 열고 이 자바스크립트 파일을 실행하면 아직까지 아무 환경 변수를 설정해주지 않았기 때문에 undefined
가 출력될텐데요.
$ node index.js
API_KEY: undefined
DB_PASSWORD: undefined
위에서 배운 방법으로 운영체제의 명령어를 이용하여 환경 변수를 설정해준 다시 실행해보면 설정한 환경 변수가 출력이 될 것입니다.
$ export API_KEY=abc
$ export DB_PASSWORD=1234
$ node index.ts
API_KEY: abc
DB_PASSWORD: 1234
물론 프로그램 실행할 때 node
명령어 앞에 환경 변수를 바로 명시해줘도 되겠죠?
$ API_KEY=def node index.js
API_KEY: def
DB_PASSWORD: 1234
이렇게 두 가지 방법을 동시에 사용할 경우, 프로그램 실행 시점에 설정된 환경 변수의 값이 운영 체제의 명령어로 설정된 환경 변수의 값보다 우선 시 되는 것을 볼 수 있습니다. 이렇게 환경 변수가 덮어써지는(overwrite) 특징은 특정 환경 변수를 일회성으로 설정하고자 할 때 매우 유용하게 활용될 수 있습니다.
전체 코드
본 포스팅에서 작성한 코드는 아래에서 직접 수정하거나 브라우저 상의 가상 터미널에서 실행해볼 수 있습니다.
마치면서
지금까지 Node.js에서 process.env
를 통해 환경 변수를 어떻게 읽고 쓰는지에 대해서 살펴보았습니다.
사실 이렇게 일일이 모든 환경 변수를 설정하는 것은 오타의 위험도 크고 지루한 작업이 될 수 있는데요. 관리해야 할 환경 변수의 수가 많아지거나 애플리케이션을 배포해야 할 환경이 늘어나면 유지 보수가 매우 괴로워지는 상황이 펼쳐지겠죠?
그래서 많은 Node.js 프로젝트에서 환경 변수를 좀 더 효과적으로 관리하기 위해서 dotenv
라는 라이브러리를 많이 사용하고 있습니다.
이에 대해서는 별도의 포스팅에서 자세히 다루도록 하겠습니다.