환경 변수 관리

Younghwan Cha·2023년 3월 7일
0

configuration

목록 보기
3/7

환경 변수 ( Environment variable )

환경 변수 는 프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는 동적인 값들의 모임이다.
프로세스를 실행하는 데 필요한 경로, 서버 환경에 필요한 설정값 및 보안과 관련된 키들을 포함하여 다양한 설정값들을 미리 저장하고 이를 관리하는 것이다. 민감한 정보들이 포함된 만큼 이를 안전하게 관리하는 것은 아주 중요한 사안이다. 따라서, 이를 저장하고 관리하기 위한 다양한 방법들이 존재한다.
최근 한 express 기반 프로젝트를 개선할 기회가 생겼는 데, 이에 대한 고민의 일환으로 환경 변수를 관리하는 방법들에 대해서 이야기 해보려 한다.


hard coding

...곤란하다
환경 변수에는 외부에 알려지면 문제가 되는 정보들이 다수 포함되기 때문에 코드내에 포함할 경우 보안상에 큰 문제가 발생한다.
특히, github 와 같은 SCM( source code management ) 를 사용할 경우 정보가 불특정 다수에게 공개 될 위험성이 더욱 커지기 때문에 위험하다.
이뿐만 아니라, 특정 환경 변수가 어디에 사용되는지 디버깅 하기 굉장히 불편하기 때문에 유지보수에도 많은 어려움이 있어 이 방법은 지양해야한다.


config module

아래와 같이 json 파일에 정의해두고 require() 을 통해서 사용하는 방법이다.
이는, 위에서 언급한 것과 같이 SCM 을 사용하여 배포할 경우 보안상에 문제가 생길 수 있기 때문에
.gitignore 파일에 config.json 을 추가하고, 대신에 config.example.json 을 작성하여 프로세스를 실행하기 위한 환경 변수들에는 어떤 것들이 있는지를 명시해줄 수 있다.

# config.json
{
  "host": "localhost",
  "user": "username",
  "password": "password",
  "database": "dbname"
}

# config.example.json
{
  "host": 
  "user": 
  "password": 
  "database": 
}

이때, local, dev, prod 와 같이 stage 에 따라서 환경 변수를 다르게 적용해야할 경우가 생길 수 있다.
이 경우, 아래와 같이 실행시에 환경 변수를 넣어주고 이에 따른 환경 변수를 가져와서 사용할 수 있다.

# package.json
{
  ...
  scripts: {
    "local": "profile=local node ./index.js
    "dev": "profile=dev node ./index.js
    "prod": "profile=prod node ./index.js
  }
}

# config.json
const profile = process.env.profile;

module.exports = {
  local: { ... },
  dev: { ... },
  prod: { ... },
}[profile]
# dbConnection.js
const { DB_HOST, DB_USER } = require("../config")['DB_CONFIG'];

[stage 별로 환경변수 관리] https://gofnrk.tistory.com/116


dotenv (.env)

.env 파일을 통해서 환경 변수를 관리하는 방법이 있다.
dotenv 라이브러리는 현재 디렉토리에 위치한 .env 파일로부터 환경 변수를 읽어온다.
dotenv 를 사용하더라도 보안문제를 피해 갈 수 없기 때문에 .gitignore 에 추가하는 것을 잊으면 안된다.

npm i dotenv
# .env
DB_HOST=localhost
DB_USER=username
// CommonJS
require("dotenv").config();

console.log(process.env.DB_HOST);

// ES module
import dotenv from "dotenv";
dotenv.config();

console.log(process.env.DB_HOST);

[es-module 발생하기 쉬운 실수] https://www.daleseo.com/js-dotenv/#es-%EB%AA%A8%EB%93%88%EC%97%90%EC%84%9C-%EB%B0%9C%EC%83%9D%ED%95%98%EA%B8%B0-%EC%89%AC%EC%9A%B4-%EC%8B%A4%EC%88%98

만약 .env.local, .env.dev, .env.prod 와 같이 .env 가 아닌 다른 이름을 사용하고 싶다면, 아래와 같이 path 를 지정하면 된다.
( 공식문서에서는 이 방법을 사용하는 것을 추천하지 않는다 )
[dotenv github] https://github.com/motdotla/dotenv#should-i-have-multiple-env-files

import dotenv from 'dotenv';

dotenv.config({ path: '.env.local' });

app.use(session({ secret: process.env.SESSION_SECRET }));

또한, debug: true 를 통해서 내가 설정하려는 환경 변수가 기존에 이미 설정되어 있었는지도 확인 할 수 있다.

import dotenv from 'dotenv';

dotenv.config({ debug: true });

app.use(session({ secret: process.env.SESSION_SECRET }));

이렇게 경로를 지정하는 방법 이외에도, dotenv 를 import 하여 dotenv.config() 를 코드내에서 호출하기 힘든 경우 아래와 같이 node command-r 혹은 --require 옵션에 dotenv/config 를 전달 하는 방법도 있다.

node -r dotenv/config index.js

DOTENV_CONFIG_PATH=.env.local node -r dotenv/config index.js

서버에 환경 변수 추가

local 에서 export PATH=$PATH:/... 을 통해서 환경 변수에 특정 경로를 추가 할 수 있다.
이처럼, 실제 프로세스를 구동하는 서버 내부에 직접 환경 변수를 추가하는 것도 하나의 방법이 될 수 있다.
대표적으로, NODE_ENV 변수를 production 혹은 development 로 지정해서 사용하는 방법이있다.

export NODE_ENV=production
if (process.env.NODE_ENV == 'production') {
  console.log("Production Mode");
} else if (process.env.NODE_ENV == 'development') {
  console.log("Development Mode");
}

이 경우, 변수 값을 확인하고 변경하는 것에는 제약이 있을 수 있으나 위에서 발생한 SCM 문제와 관련해서는 신경쓰지 않아도 되지 때문에 개발자들의 실수를 줄일 수 있다는 이점을 갖고있다.

profile
개발 기록

0개의 댓글