# [node] NodeJS 환경변수 .env 다루기 1탄
2025. 1. 22. 09:57ㆍ개발/Node
9.1 환경 변수 소개
- 다양한 환경의 외부 애플리케이션과 연동 할수 있음.
- 최소한의 경우 데이터베이스 설정 필수
- 배포를 어떤 환경에 하느냐에 따라 테스트용, 프로덕션용을 나누어야함.
- QA 환경도 필요함.
- 이외에 소스 코드에 들어가면 안된느 민감한 값 등 최소한 환경변수로 설정하거나 vault 같은 소스코드 이외의 외부 저장소에 두어야함. 예를들어 몽고디비 패스워드같은것.
- 코드로 제어하지 말고 별도의 파일로 두어서 외부 서버에 설정해서 읽어올수있도록 해야함.
- 그렇지 않으면 설정이 복잡해질수록 환경 변수를 제어하는 코드가 복잡해짐
- NestJS 환경변수 설정은 ConfigModule 에서 할수있고 설정된 환경변수를 다른 모듈에서 가져다쓰려면 ConfigService 를 주입 받아 사용해야함.
9.2 프로젝트 생성 및 설정
(1) 환경설정 파일 테스트용 사용할 config-test 이름으로 NestJs 프로젝트 생성후 의존성 패키지 설치
nest new config-test
cd config-test
npm i @nestjs/config ## 의존성 패키지 설치
- nestjs/config 는 내부적으로 dotenv 를 사용함.
- .dotenv 는 .env 라는 이름의 파일에 환경변수를 설정하고 불러올수있게 하는ㄴ 자바스크립트 라이브러리
9.3 NestJS 설정 및 테스트
순서 : app.module.ts - ConfigModule 설정 > .env 파일 생성 > app.controller.ts 에 테스트 라우팅 함수 추가
9.3.1 app.module.ts 에 ConfigModule 설정
(1) ConfigModuel
- 설정에 특화 된 기능 모듈
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; // config importiing import { AppController } from './app.controller'; import { AppService } from './app.service';
@Module({
imports: [ConfigModule.forRoot()], // config moudle 설정
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- ConfigModule.forRoot() 옵션
|옵션|설명|
|--|--|
|cache|메모리 환경변수 캐시 여부 |
|isGlobal|다른 모듈에서 임포트 안해도 사용가능|
|ignoreEnvFile|.env 파일 무시|
|ignoreEnvVars|환경 변수 무효|
|envFilePath|환경변수 파일 경로|
|encoding|환경변수 파일 이코딩|
|validate|환경 변수 유효성 검증 함수|
|load|커스텀 환경 설정 파일을 로딩시에 사용,ts,yaml 등 |
## 9.3.2 .env 파일 생성
### (1) .env 작성
- .env: @nestjs/config 내부에서 사용하는 dotenv 라이브러리에서 환경 변수 파일 읽어올때 사용하는 파일
- dotenv : 기본적으로 .env 확장자 파일 읽어옴.
- 프로젝트 루트 디렉터리 바로 아래 .env 파일 생성후 작성
```Bash
vi /test-config/.env
####################
MESSAGE=hello nestjs
####################
- MESSAGE 가 key 이고 hello 가 value
- = 사이 공백은 무시, 키는 보통 대문자로 함.
- 맥에서는 env 명령실행시 시스템 환경 변수 확인 가능
9.3.3 app.controller.ts 코드 추가
(1) getHello() 함수를 수정해 .env 환경변수를 사용.
import { Controller, Get } from '@nestjs/common';
// Configure
import { ConfigService } from '@nestjs/config';
import { AppService } from './app.service';
@Controller()
export class AppController {
// ConfigService 주입
constructor(private configService: ConfigService){}
@Get()
getHello(): string {
// configService.get() 호출
const message = this.configService.get("MESSAGE")
return message
}
}
9.3.4 테스트
9.4 ConfigModule 을 전역 모듈로 설정하기
(1) ConfigService 사용할 수있어야함.
isGlobal 옵션을 사용하도록 app.module.ts 의 ConfigModule 의 설정을 수정
@Module({
imports: [ConfigModule.forRoot({ isGlobal: true})],
9.4.1 .env 환경변수 설정
(1) .env 에 변수 추가
vi .env
###################################
WEATHER_API_URL = http://api.openweathermap.org/data/2.5/forecast?id=524901&appid=
WEATHER_API_KEY = my_open_api_key
###################################
nest g module weather ##
nest g controller weather --no-spec
9.4.3 날씨 api 테스트용 핸들러 함수로 테스트
weather.controller.ts 작성
// weather/weather.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Controller('weather')
export class WeatherController {
constructor(private configService: ConfigService){}
@Get()
public getWeather(): string {
// 환경 변수 값 가져 오기
const apiUrl = this.configService.get('WEATHER_API_URL')
const apiKey = this.configService.get('WEATHER_API_KEY')
// 내부함수인 callWeatherAPI() 호출
return this.callWeatherApi(apiUrl, apiKey)
}
private callWeatherApi(apiUrl: string, apiKey: string): string {
console.log('날씨 정보 가져오는중 ...')
console.log(apiUrl)
console.log(apiKey)
return '내일은 맑음 '
}
}
실제로 api 서비스를 해보기
npm install axios ## api 요청을 위한 라이브러리
weather.controller.ts 작성
import { Controller, Get, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
// api 요청 라이브러리
import axios from 'axios';
@Controller('weather')
export class WeatherController {
// logger 선언
private readonly logger = new Logger(WeatherController.name)
constructor(private configService: ConfigService){}
@Get()
public async getWeather(): Promise<string> {
// 환경 변수 값 가져 오기
const apiUrl = this.configService.get<string>('WEATHER_API_URL')
const apiKey = this.configService.get<string>('WEATHER_API_KEY')
console.log(apiUrl)
console.log(`apiUrl type : ${typeof apiUrl}`)
// 내부함수인 callWeatherAPI() 호출
try {
const weatherData = await this.callWeatherApi(apiUrl, apiKey)
return weatherData
} catch (error) {
this.logger.error('Error fetching weather data', error.stack)
return '날씨 정보 가져오는것 실패'
}
}
private async callWeatherApi(apiUrl: string, apiKey: string): Promise<string> {
console.log('함수 진입')
this.logger.log('날씨 정보 가져오는중 ...')
console.log(apiUrl)
// this.logger.log(`API URL : ${apiUrl}${apiKey}`)
console.log("asfdaf")
try {
const response = await axios.get(apiUrl, {
params: {
appid: apiKey,
q: 'Seoul' // 서울 날씨
}
})
// this.logger.debug(`API response: ${JSON.stringify(response.data)}`)
// 응답 데이터에서 필요한 정보 추출
const forecast = response.data.list[0];
const description = forecast.weather[0].description;
const temp = forecast.main.temp;
const humidity = forecast.main.humidity;
// 추출한 정보로 문자열 생성
return `내일의 날씨는: ${description}, 온도: ${temp}K, 습도: ${humidity}%`
} catch (error) {
this.logger.error('Error occurred api call',error.stack)
throw new Error('api call fail')
}
}
}
9.5 여러 환경변수 파일 사용
- 현업에서는 dev, qa, beta, prod 용 환경변수를 만듬.
- NODE_ENV 에 값을 할당해 환경별로 서버 설정을 다르게 적용 할수 있음
9.5.1 환경별로 서버가 기동되도록 스크립트 수정
(1) local,dev,prod 환경에서 서버기동 package.json 의 script 항목에 스크립트 추가해야함.
start, start:dev, start:prod 를 수정
"start": "NODE_ENV=local&& nest start",
"start:dev": "NODE_ENV=dev && nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "NODE_ENV=prod&& node dist/main",
9.5.2 local, dev, prod 환경 변수 생성
(1) 프로젝트 root에 envs 라는 디렉토리 생성
(2) envs/prod.env > SERVICE_URL = http://localhost:3000
등으로 각각 dev.env, local.env , prod.env 를 생성하여 service url 을
분류하여 나눈다.
9.5.3 환경변수에 다라 다른 환경 변수 파일을 사용하도록 설정 수정
(1) app.module.ts 를 수정
@Module({
imports: [ConfigModule.forRoot({
isGlobal: true,
envFilePath : `../envs/${process.env.NODE_ENV}.env`,
ignoreEnvFile : false
}), WeatherModule],
- {process.cwd()} 이게 안먹는것같아서 .. 으로 대체하니 해결됨
9.5.4 테스트용 핸들러 함수로 테스트
(1) http://localhost:3000/service-url 에 접속해 환경별로 추가한 service_url 환경변수가 화면에 표시되도록 테스트
9.6 커스텀 환경설정 파일 사용하기
9.6.1 환경 변수 파일 생성
(1) 실행 시 logLevel, apiVersion, MESSAGE 등 공통으로 사용할 환경 변수 정의하는 파일을 정의 configs/config.ts, configs/dev.ts,configs/local.ts, configs/prod.ts
// configs/config.ts
import common from "./common";
import local from "./local";
import dev from "./dev";
import prod from "./prod";
const phase = process.env.NODE_ENV
let conf = {}
if (phase === 'local') {
conf = local
} else if (phase ==='dev') {
conf = dev
} else if (phase ==='prod') {
conf = prod
}
export default () => ({
...common,
...conf
})
// configs/common.ts
export default {
logLevel: 'info',
apiVersion: '1.0.0',
MESSAGE : 'hello'
}
// configs/dev.ts
export default {
logLevel: 'debug',
dbInfo: 'http://dev-mysql:3306'
}
// configs/local.ts
export default {
dbInfo: 'http://localhost:3306'
}
// configs/prod.ts
export default {
logLevel: 'error',
dbInfo: 'http://prod-mysql:3306'
}
9.6.2 ConfigModule 에 load 옵션 추가
(1) 커스텀 파일 설정을위해 load 옵션 추가
@Module({
imports: [ConfigModule.forRoot({
isGlobal: true,
envFilePath : `../envs/${process.env.NODE_ENV}.env`,
// ignoreEnvFile : false,
// load 옵션을 사용해 커스텀 설정 파일 추가
load: [config]
9.7
'개발 > Node' 카테고리의 다른 글
#[node] 환경변수 2탄 (0) | 2025.01.23 |
---|---|
#[node] 회원 가입 로그인 (0) | 2025.01.23 |
[node] Chapter 7. 페이지 네이션 되는 게시판 만들기 (0) | 2025.01.21 |
Chapter 8. NestJS (0) | 2025.01.21 |
# [node]패키지 매니저 npm , 사용해보자 (0) | 2025.01.10 |