@nestjs/config

Tags
npm
설명
env 설정
 
 

설치

$ npm i --save @nestjs/config
💡
@nestjs/config는 내부적으로 dotenv 을 이용한다.
 

NestJS 설정

app.module.ts 파일의 imports 란에 아래와 같이 추가한다.
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ConfigModule.forRoot({isGlobal:true})], // isGlobal은 앱 어디에서나 config 모듈에 접근할 수 있도록 한다. }) export class AppModule {}
 
기타 ConfigModuleOptions 타입을 보면 아래와 같다.
export interface ConfigModuleOptions { /** * If "true", values from the process.env object will be cached in the memory. * This improves the overall application performance. * See: https://github.com/nodejs/node/issues/3104 */ cache?: boolean; /** * If "true", registers `ConfigModule` as a global module. * See: https://docs.nestjs.com/modules#global-modules */ isGlobal?: boolean; /** * If "true", environment files (`.env`) will be ignored. */ ignoreEnvFile?: boolean; /** * If "true", predefined environment variables will not be validated. */ ignoreEnvVars?: boolean; /** * Path to the environment file(s) to be loaded. */ envFilePath?: string | string[]; /** * Custom function to validate environment variables. It takes an object containing environment * variables as input and outputs validated environment variables. * If exception is thrown in the function it would prevent the application from bootstrapping. * Also, environment variables can be edited through this function, changes * will be reflected in the process.env object. */ validate?: (config: Record<string, any>) => Record<string, any>; /** * Environment variables validation schema (Joi). */ validationSchema?: any; /** * Schema validation options. * See: https://joi.dev/api/?v=17.3.0#anyvalidatevalue-options */ validationOptions?: Record<string, any>; /** * Array of custom configuration files to be loaded. * See: https://docs.nestjs.com/techniques/configuration */ load?: Array<ConfigFactory>; /** * A boolean value indicating the use of expanded variables, or object * containing options to pass to dotenv-expand. * If .env contains expanded variables, they'll only be parsed if * this property is set to true. */ expandVariables?: boolean | DotenvExpandOptions; }

ENV 세팅 팁

dev, test, prod 별로 env 설정을 다르게 하고 싶다.

cross-env 설치

$ npm i cross-env

env 파일 생성

notion image
 
notion image
git에 올라가지 않도록, 생성한 env 파일명을 .gitignore에 명시해주는 것도 잊지말자

환경변수 값 대입 방법

"start:dev": "cross-env NODE_ENV=dev nest start --watch",
이런 식으로 cross-env 변수명=값 이렇게 설정할 수 있다.
이번에는 NODE_ENV라는 변수에 dev라는 값을 넣어줬다.

envFilePath 설정

app.module.ts 파일에서 ConfigModule 설정 시 옵셔널 인자로 envFilePath를 설정할 수 있는데, 여기서 활용하자.
ConfigModule.forRoot({ isGlobal: true, envFilePath: process.env.NODE_ENV === 'dev' ? '.env.dev' : '.env.test', }),

PRD 환경에선 env 파일 사용하지 않도록 설정

환경변수 파일이 아니라, 환경변수를 파일이 아닌 환경변수 관리 서버 등 다른 방식으로 얻어오도록 하고 싶은 경우
특히 prd 환경 배포 시에 이런 설정을 많이 한다.
 
이럴 때는 ignoreEnvFile 옵션을 이용하면 된다.
ConfigModule.forRoot({ isGlobal: true, envFilePath: process.env.NODE_ENV === 'dev' ? '.env.dev' : '.env.test', ignoreEnvFile: process.env.NODE_ENV === 'prd', }),
 

활용 예시

typeORM 사용 시 DB 연결정보를 코드상에 노출하지 않고, env 파일에서 가져오도록 하고 싶다.
 
// app.module.ts imports: [ ..., TypeOrmModule.forRoot({ type: 'postgres', host: process.env.DB_HOST, port: +process.env.DB_PORT, username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, synchronize: true, logging: true, // 콘솔에 출력 }), ]
 
# .env.dev 파일 DB_HOST=localhost DB_PORT=5432 DB_USERNAME=username DB_PASSWORD=12345 DB_NAME=nuber-eats
 

환경변수 유효성 검사

 
필요한 환경변수들이 준비되지 않았다면 앱이 실행되지 않도록 하는 설정이다.
ConfigModuleOptions에서 validationSchema 옵션을 이용하면 된다.
 
해당 옵션의 주석에도 쓰여있듯, joi를 활용하므로 설치하자.

joi 설치

joi
hapijsUpdated Mar 22, 2025
$ npm install joi
 
import * as Joi from 'joi'; @Module({ imports: [ ConfigModule.forRoot({ validationSchema: Joi.object({ NODE_ENV: Joi.string() .valid('development', 'production', 'test', 'provision') .default('development'), PORT: Joi.number().port().default(3000), }), }), ], }) export class AppModule {}
위와 같이 Joi를 이용해서 유효성 검사를 하면 된다.
타입과 유효한 값 나열, required 여부 등을 명시하여 유효성 검사를 진행할 수 있다.
(당연히 regex도 이용할 수 있다)
 
// validationSchema 작성 예시 validationSchema: Joi.object({ NODE_ENV: Joi.string().valid('dev', 'prod').required(), DB_PORT: Joi.number().port().required(), DB_USERNAME: Joi.string().required(), DB_PASSWORD: Joi.string().required(), DB_NAME: Joi.string().required(), }),
 

유효성 테스트

notion image
테스트를 위해 임의로 환경변수 하나를 제거한 후 테스트했다.
 
사실 localhost로 접속하는 경우 postgresql에서 패스워드 체크를 하지 않고 연결을 허용하기 때문에 환경변수가 반드시 있어야 하는 상황은 아니다.
하지만 Joi를 통해 required()로 유효성 체크를 걸어놨기 때문에, 환경변수에 해당 값이 없자 에러를 띄우는 모습이다.
 

Module에서 환경변수 사용하는 방법

물론 process.env.값 이렇게 가져와도 되지만, 이건 nestjs의 방식이 아니다.
환경변수를 사용하고자 하는 곳의 Module에 Configuration을 import 시켜주는 방식이 권장된다.
 
를 보면 최상단인 app.module.ts에 필요한 Configuration 설정들을 해두었다.
이후 모듈,서비스 등 필요하다면 요청만 하면 알아서 inject 시켜주는 방식으로 nestjs에서 동작한다.

모듈에서의 설정

일반적인 모듈이라면 users.module.ts 에서 ConfigService를 import 해야겠지만,
ConfigService 모듈이 global module 이기 때문에 따로 다른 module에서 별도로 import를 하지 않아도 된다.

서비스에서의 설정

app.module.ts 에서 configuration 설정을 이미 다 했으므로 nestjs는 환경변수 정보를 알고 있다.
필요한 곳에서 @nest/config 로부터 ConfigService를 가져와서 넣어주기만 하면 환경변수 값들을 자유롭게 이용할 수 있다.
// users.service.ts import { ConfigService } from '@nestjs/config'; export class UsersService { constructor( @InjectRepository(User) private readonly users: Repository<User>, private readonly config: ConfigService, ) {} ... login(){ const token = jwt.sign({ id: user.id }, this.config.get('SECRET_KEY')); } }
this.config.get(’환경변수명’)