설치NestJS 설정ENV 세팅 팁cross-env 설치env 파일 생성환경변수 값 대입 방법envFilePath 설정PRD 환경에선 env 파일 사용하지 않도록 설정활용 예시환경변수 유효성 검사joi 설치유효성 테스트Module에서 환경변수 사용하는 방법모듈에서의 설정서비스에서의 설정
설치
$ 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 파일 생성


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
hapijs • Updated 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(), }),
유효성 테스트

테스트를 위해 임의로 환경변수 하나를 제거한 후 테스트했다.
사실 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(’환경변수명’)