본문 바로가기

프로그래밍 공부내용/자바스크립트(JS)

배포할 때 환경변수 숨기기(with dotenv)

지금까지는 개인 dev에서만 확인 할 수 있는 개발을 해왔었습니다.

 

백엔드와 협업을 할 때에도 연결되는지와 결과물이 잘 나오는지만 봤지 실제 프로덕트로 이어지지는 않았었습니다.

 

우테코 lv3를 진행하면서 실 사용이 가능한 서비스를 만들기 위해서 배포를 하고, 오픈소스로 git 레포를 관리하다보니

 

ip와 같은 환경변수들을 숨겨야 할 일이 생겼습니다.

 

수동으로 같이 작업하는 사람들끼리만 알고 있다가 배포할 수 도 있지만,

 

현재 프로세스에서 젠킨스 등 다양한 도구를 사용하고 있기 때문에 자동화가 가능할 것이라고 생각했습니다.

 

작업은 아래와 같이 진행하였습니다.

 

1. .env 분리하기 

//.env
API_URL = http://localhost:3000

와 같은 식으로 .env파일을 src 디렉토리 아래에 분리해줍니다.

 

2. .env를 load해주는 라이브러리 dotenv

npm이나 yarn을 이용해서 dotenv를 다운받아줍니다.

dotenv는 현재 디렉토리들을 찾으면서 .env로 된 환경변수들을 키=값으로 로드해 줍니다.

 

 

3. 배포하는 env관리

배포시에 젠킨스 ec2 서버에서 build후 프론트 엔드 ec2 서버로 보내주는 구조였습니다.

젠킨스 ec2에서 .env를 가지고 있다가 프론트엔드 ec2로 보내줘야 하는데,

젠킨스에서 직접 .env를 똑같이 만들어 줄 수 도 있었지만, 안만들고 스크립트에 넣어서 할 수 있었습니다.

젠킨스의 설정에 넣어줄 수 도 있고, 파이프라인에 직접 담아줘서 백엔드 환경변수로 흘러들어가지 않도록 해 줬습니다.

pipeline {
    agent any
    environment { 
        API_URL = 'http://localhost:3000'
    }
    stages {
        stage('A') 
            steps {
                sh '....'
            }
        }
    }
}

이렇게 하면 젠킨스 ec2에 .env를 생성한 것 처럼 환경변수가 설정 됐습니다.

 

4. 배포시에는 mode = production

젠킨스가 build 후 배포 한 녀석은 production으로 알아서 잘 인식합니다.

안된다면 package.json의 script에서 빌드명령어에 webpack 설정을 이용해서 production으로 만들어주면 될 것 같습니다.

 

5. 개발환경에서는 mode dev와 local 분리하기

localhost만 써서 mock으로 개발할 수 있지만, 백엔드에서 dev용 test server를 따로 개설해줘서 

yarn dev와 yarn local을 분리해 줬습니다.

//package.json

"scripts": {
    "local": "webpack server --mode development --env  MODE=local --open --hot",
    "dev": "webpack server --mode development --env MODE=development --open --hot",
    "prod": "webpack server --mode development --open --hot",
    "build": "webpack --mode production"
  },

처럼 해 줬더니 해결 됐습니다.

 

--env 덕분에 Mode=local 로 설정해 줄 수 있습니다.(https://webpack.js.org/guides/environment-variables/)

const path = require('path');

module.exports = (env) => {
  // Use env.<YOUR VARIABLE> here:
  console.log('Mode: ', env.Mode); // yarn local이면 'local',  yarn dev면 'dev'

  return {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
  };
};

처럼 됩니다.

 

 

definePlugin을 이용해서 JS 전역으로 사용되는 전역변수를 선언해 주거나, EnvironmentPlugin을 사용해도 됩니다.

environmentPlugin은 node환경에서 돌아갑니다.

  //.env
  API_URL = {ip 주소}
  
  
  //webpack.config
  new webpack.DefinePlugin({
        'process.env.API_URL': JSON.stringify(process.env.API_URL),
  }),

와 같이 구성해서 api_url을 전역으로 쓸수 있게 process.env.API_URL이라는 녀석으로 선언해 줬습니다.