환경변수 적용
서버를 돌리기 위해 꼭 필요한 값들이 있다. 예를 들자면, DB Connection 정보나 서버 Port, AWS Key와 같은 값들이 있다.
이런 값들은 주로 환경변수로 분리하는데, 분리함으로서 아래와 같은 이점들을 얻을 수 있다.
- 보안: 외부에 노출되면 큰일나는 민감한 값들을 소스코드에 하드코딩하지 않음으로써, 소스코드가 노출되어도 외부에서 민감한 정보들을 알 수 없도록 보안을 강화할 수 있다.
- 유연성: 소스코드를 직접 수정하지 않고도 값들을 변경할 수 있기에, 서버를 다시 빌드하지 않고도 환경을 설정할 수 있다.
- 배포 관리의 용이: .env.development, .env.production과 같이 서버가 실행되는 환경에 따라 불러올 환경변수 파일을 다르게 함으로써, 여러 환경에 쉽게 배포할 수 있다.
보통 Javascript에선 dotenv 라이브러리를 사용하는데, NestJS에선 @nestjs/config 모듈을 주로 사용한다. 이번 시간엔 NestJS에서 환경변수 설정하는 방법에 대해 알아보자.
ConfigModule 설정
NestJS에서 환경변수를 불러오기 위해 ConfigModule을 사용해야 하는데, 이 모듈은 @nestjs/config 패키지에 있다.
Nest Project 생성 시 자동으로 추가되는 모듈이 아니기 때문에, 수동으로 추가해줘야 한다.
npm i @nestjs/config
@nestjs/config도 내부적으로는 dotenv를 사용한다.@nestjs/config의 package.json을 뜯어보면 dotenv가 dependencies에 들어있는것을 볼 수 있다.
다만 NestJS는 모듈 기반으로 동작하기 때문에, dotenv를 사용하려면 모듈로 감싸줘야 한다. @nestjs/config에서 이미 dotenv를 모듈화 해줬을 뿐더러, 다른 추가 기능들도 지원하니 굳이 dotenv를 사용할 필요는 없다.
설치가 되었다면 NestJS에서 모듈을 인식하기 위해 app.module.ts에 ConfigModule을 등록해줘야 한다.
@Module의 imports에 ConfigModule이, providers에 ConfigService가 추가되었다.
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [ConfigModule.forRoot({ isGlobal: true })],
controllers: [AppController],
providers: [AppService, ConfigService],
})
추가된 코드가 하는 역할은 다음과 같다.
- ConfigModule.forRoot(option): ConfigModule에 option을 적용하고 DynamicModule 객체를 반환한다. 이 코드가 있어야 모듈이 등록되어 환경변수를 불러올 수 있다.
- ConfigService: 다른 Service들에서 ConfigService를 Inject 받아 환경변수 값을 가져올 수 있게 해준다.
ConfigModule 적용 확인
이제 ConfigModule이 환경변수를 잘 불러오는지 테스트해보자.
AppService의 getHello에서 ConfigService를 주입받도록 constructor에 넣어주고, 'TEST'를 읽어오도록 수정했다.
// .env
TEST='test'
@Injectable()
export class AppService {
constructor(private readonly configService: ConfigService) {}
getHello(): string {
return `Hello World! ${this.configService.get<string>('TEST', 'default')}`;
}
}
이제 localhost:3000에 접속하여 'Hello World! default'가 아닌 'Hello World! test'가 보이면 된다.
환경변수 로딩 함수 지정
ConfigModule은 .env 파일이 아니더라도, Load 함수를 지정하여 함수의 반환값을 사용해 config에 넣어주기도 한다.
이 기능을 통해 다른 서버에서 파일을 읽어오는 함수를 추가해 Config 파일을 원격에서 관리하도록 하는 등 편하게 사용할 수 있다.
ConfigModule.forRoot 옵션 내에 load를 추가하여 구현할 수 있다.
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
const loadConfigsFromRemote = async () => {
// 원격에서 Config 파일을 읽어오는 코드 작성
return { HOST: 'host' };
};
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [loadConfigsFromRemote], // load 함수 추가
}),
],
controllers: [AppController],
providers: [AppService, ConfigService],
})
export class AppModule {}
load는 배열 형태라, 환경변수 로딩 함수를 여러 개 등록할 수 있다.
여러 함수에서 같은 환경변수 이 로딩될 수도 있는데, 이 경우 먼저 로딩된 값이 환경변수에 반영된다.
참고자료
'Study > NestJS' 카테고리의 다른 글
[NestJS] 1. 프로젝트 개발환경 구성 (1) | 2023.12.19 |
---|