해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다.
모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다.
#pre. 터미널을 켜고 프로젝트 폴더로 이동
위의 링크의 내용을 참고하여 study 폴더로 이동해줍니다.
그리고 code . 명령어를 통해 vscode를 열어줍니다.
이전 포스팅에서, DB구조를 설계하고 TypeORM을 이용해 DB 테이블들을 생성해 보았습니다.
이번 포스팅에서는 Nest.js와 DB를 연동할 때 소스코드에 입력하는 중요한 정보들을 감출 수 있도록 하는 환경변수 설정에 대해서 알아보겠습니다. 이를 이용하면 Github에 DB비밀번호나 시크릿 키 같은 중요한 정보들을 올리지 않아도 됩니다.
ConfigModule
환경변수란?
- 정의 : 환경 변수는 프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는, 동적인 값들의 모임이다.
- 환경변수란 간단히 말해서 환경설정에 사용되는 변수라고 생각합시다.
- 환경변수는 소스코드가 아닌 컴퓨터 자체(아마도 프로세스)에 저장되는 변수값인데, 이를 활용함으로서 사용자는 자신이 공유하고 싶지 않은 변수 값을 환경변수에 저장하여 사용할 수 있습니다.
ConfigModule이란?
- .env 파일에서 정의된 환경변수를 사용하게 해주는 모듈
- env파일을 dotenv를 사용하지 않고 모듈화하여 유연하게(동적이게) 사용할 수 있게 해줍니다.
- Nest.js의 Module 이외에는 사용이 불가하다는 것에 주의! (ex. data-source.ts같은 파일에는 사용 불가)
- ConfigModule 사용시 ConfigService를 주입해서 사용합니다.
Start
먼저, @nestjs/config 모듈을 설치합니다.
npm i @nestjs/config
그 후, app.module.ts에 ConfigModule을 import합니다.
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as path from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './res/user/user.module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forRootAsync({
useFactory: () => ({
...
}),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
여기서, ConfigModule.forRoot로 AppModule의 ConfigModule을 imports안에 넣어줍니다.
envFilePath: `env.${process.env.NODE_ENV}` 옵션을 넣어준 이유는 NODE_ENV라는 환경변수에 따라 env파일을 다른 것을 사용하겠다는 뜻입니다. 예를들면, test환경에는 NODE_ENV = test로 설정하여 DB의 세팅을 test환경으로 세팅할 수 있고, dev환경에면 NODE_ENV = dev로 설정하여 DB의 세팅을 dev환경으로 세팅할 수 있습니다. 이건 다음 포스팅에서 설명하겠습니다. 일단 설정하지 맙시다.
isGlobal: true 옵션을 설정해 주어야 다른 모듈에서 별도의 설정없이 환경변수의 사용이 가능합니다.
자, 그러면 이제 ConfigService를 이용해서 환경변수를 사용할 수 있습니다.
AppModule의 TypeOrmModule부터 고쳐봅시다!
다음과 같이 고칠 수 있습니다.
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as path from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './res/user/user.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forRootAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
retryAttempts: configService.get('NODE_ENV') === 'prod' ? 10 : 1,
type: 'mysql',
host: configService.get('DB_HOST'),
port: Number(configService.get('DB_PORT')),
database: configService.get('DB_NAME'),
username: configService.get('DB_USER'),
password: configService.get('DB_PASSWORD'),
entities: [
path.join(__dirname, 'src/entities/**/*.entity.{js, ts}'),
],
synchronize: false,
logging: true,
timezone: 'local',
}),
}),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
일단, inject를 이용해 ConfigService를 주입해줍니다. (이해 안되면 그런가보다~ 하고 넘어갑시다!)
그리고, useFactory의 인자로 configService를 받아서 사용합니다.
retryAttempts: configService.get('NODE_ENV') === 'prod' ? 10 : 1 NODE_ENV라는 환경변수의 값이 prod면 재연결 시도를 10번하고 아니면 1번 한다는 뜻입니다.
configService.get('환경변수명') 환경변수명에 해당하는 환경변수의 값을 가져옵니다.
예를들어, .env파일에서 DB_HOST=localhost 로 설정했다면, host: configService.get('DB_HOST') 는 host: 'localhost' 와 동일하다고 보면 됩니다.
.env 파일 생성
ConfigModule 세팅이 끝났으니, 환경변수를 관리하기 위한 .env 파일을 만들어봅시다.
.env 파일을 프로젝트 폴더 최상위에 위치하면 됩니다.
그리고 다음과 같이 타이핑을 합시다.
// .env
DB_HOST=localhost
DB_PORT=3306
DB_NAME=study
DB_USER=DB에 사용하는 유저이름
DB_PASSWORD=DB에 사용하는 유저 비밀번호
환경변수는 기본적으로 문자열 취급이기 때문에 따옴표는 붙이지 않아도 됩니다.
이러면 ConfigModule을 이용한 환경변수 관리는 끝!
dotenv
dotenv는 ConfigModule과는 다르게 정적으로 환경변수를 불러옵니다. 그렇기 때문에 dotenv를 사용할거면, 환경변수를 이용하는 모든 파일에 dotenv.config() 설정을 해주어야 합니다.
data-source.ts에는 configModule의 사용이 불가능하니 dotenv를 사용해야합니다.
Start
dotenv모듈을 설치합니다.
npm i --save-dev dotenv
schema:sync할 때에만 data-source.ts파일을 사용할 예정이므로, devDependencies로 설치합니다.
그 후, data-source.ts 파일을 다음과 같이 수정해줍니다.
import * as path from 'path';
import { DataSource } from 'typeorm';
import * as dotenv from 'dotenv';
dotenv.config();
export const dataSource = new DataSource({
type: 'mysql',
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
database: process.env.DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
entities: [
path.join(__dirname, 'src/entities/**/*.entity.ts'),
path.join(__dirname, 'dist/entities/**/*.entity.js'),
],
synchronize: false,
logging: true,
});
import * as dotenv from 'dotenv'; 를 해주어야 합니다.
dotenv.config(); dotenv를 이용하여 환경 변수를 불러오겠다고 선언합니다.
dotenv를 사용할 경우에는 configService.get을 이용하여 환경변수를 불러오는게 아니라 그냥 process.env.환경변수명 을 통해서 환경변수를 불러올 수 있습니다.
그리고 npm run schema:sync를 터미널에 입력해서 정상작동하면 잘 설정된 것입니다.
주의사항
.gitignore 파일에 .env 가 등록이 되어 있어야 .env파일까지 올라가 버리는 참사가 일어나지 않으므로, 꼭 .gitignore파일에 .env파일을 등록해줍시다.
.env 파일을 공유할 일이 있으면 github에 올리지 않고, 개인적으로 공유하면 됩니다.
Github에 Push
이제 밑의 글을 참고하여 github에 코드를 push 합시다.
https://suloth.tistory.com/46
참고하시라고 올려두는 사진
'Back-end > 기초부터 따라하는 nest.js' 카테고리의 다른 글
#8. 기초부터 따라하는 Nest.js : TypeORM을 이용한 간단한 API작성 (6) | 2023.04.17 |
---|---|
#7. 기초부터 따라하는 Nest.js : cross-env를 이용한 scripts에서의 환경변수 관리 (0) | 2023.04.02 |
#5. 기초부터 따라하는 Nest.js : 간단한 DB구조 설계 및 TypeORM을 이용한 Entity 작성 (0) | 2023.03.23 |
#4. 기초부터 따라하는 Nest.js : TypeORM과 DB연동 (0) | 2023.03.22 |
#3. 기초부터 따라하는 Nest.js : 간단한 API 제작 (0) | 2023.03.12 |