nestjs 환경변수 설정하기

바그다드·2024년 2월 1일
0

1. 패키지 설치

먼저 환경변수 설정을 위한 패키지를 설치해줍니다.

$ npm i --save @nestjs/config

2. 환경변수 설정

환경변수 설정을 위한 임시 파일을 생성해줍니다.
.env 파일을 활용할 수도 있지만 여기서는 .yaml형식을 사용합니다.

  • development.yaml
db:
  host: 222.222.222.222
  user: development.yaml
  password: aaa
  synchronize: true
  • test.yaml
db:
  host: 111.111.111.111
  user: test.yaml
  password: test
  synchronize: true

3. 환경변수를 객체로 변환

환경변수를 key, value형태의 객체로 변환하기 위한 로직을 작성해줍니다.

// 파일명 : configuration-yaml.ts
// 환경변수에 따라 설정 파일 이름을 결정
const YAML_CONFIG_FILENAME = `${process.env.NODE_ENV}.yaml`;
const YAML_CONFIG_PATH = join(__dirname, YAML_CONFIG_FILENAME);
console.log('경로 ', YAML_CONFIG_PATH);

export default () => {
    return yaml.load(
        readFileSync(YAML_CONFIG_PATH, 'utf-8')
    ) as Record<string, any>;
};

${process.env.NODE_ENV}.yaml;
어떻게 보면 여기서 가장 눈여겨보아야 할 부분 중 하나입니다.
프로젝트를 시작할 때 지정된 환경변수를 가지고 와서 그에 따라 각자 다른 파일을 로드합니다.

4. 환경변수 등록

이제 환경변수를 프로젝트에서 사용할 수 있도록 모듈에 등록해줍니다.

// app.module.ts

import configurationYaml from './config/configuration-yaml';

    ConfigModule.forRoot({
      // 배열을 통해 여러 경로를 지정할 수 있으며 앞에 있는 변수가 우선 적용
      envFilePath: [`config/.env.${process.env.NODE_ENV}`],
      ignoreEnvFile: true,
      // 환경변수를 전역으로 사용할 시 설정
      isGlobal: true,
      load: [configurationYaml],
      validate
    }),
  • envFilePath
    .env파일의 경로를 작성해주면 됩니다. .env파일을 사용하지 않는다면 작성하지 않아도 됩니다.
  • ignoreEnvFile
    .env파일을 무시할지에 대한 속성값입니다. 여기서는 해당 옵션을 지정했습니다.
  • isGlobal
    환경변수를 전역에서 사용할지를 결정하는 옵션입니다.
  • load
    config모듈에 등록할 환경변수 파일을 등록하는 옵션입니다.
    여기서는 yaml을 configuration-yaml.ts에서 값을 파일을 읽어오므로 이 파일을 등록합니다.

5. ConfigService 활용

모듈에 정상적으로 등록까지 완료했다면 configService를 주입받아 환경변수를 활용할 수 있습니다.
먼저 development.yaml파일을 기준으로 설명을 해보겠습니다.

@Injectable()
export class MemberService {

    constructor(
        private jwtService: JwtService,
        private configService: ConfigService
    ){
        const dbConfig = this.configService.get("db", "default");
        console.log('환경변수 테스트', dbConfig);
        
    }

  • this.configService.get("키", "default값");
    configservice의 get('key')메서드를 활용해 읽어들인 환경변수 값을 가져올 수 있습니다.
    여기서는 db라고 키를 지정했으므로 get('db')로 값을 가져옵니다.
    로그를 확인해보면 객체 형태로 환경변수가 잘 저장된걸 확인할 수 있습니다.
    • 만약 첫번째 인자로 지정한 key와 일치하는 값이 없다면 두번째 인자로 지정한 값이 출력됩니다.

이런 방식으로 하다보면 단순 문자열이라 키 값이 일치하는지 확인하기 어렵습니다.
따라서 nest공식 문서에서 설명하는 타입 지정 방식을 조금 응용해 타입을 지정해보겠습니다.

6. ConfigService 활용 - 타입 선언

인터페이스 작성

export interface ConfigKey {
    db: DbConfig
}

export interface DbConfig{
    host: string;
    user: string;
    synchronize: boolean;
    password: string;
}

yaml에 지정된 depth에 따라 인터페이스를 작성하였습니다.
이제 타입을 지정해서 설정값을 가져와보겠습니다.

@Injectable()
export class MemberService {

    constructor(
        private configService: ConfigService<ConfigKey>
    ){
        const dbConfig: DbConfig = this.configService.get("dbfdfdf");
        console.log('환경변수 테스트', dbConfig);
    }


일부러 잘못된 키 값을 입력한 결과 컴파일 단계에서 에러가 발생시키는 것을 확인할 수 있습니다.

  • 올바르게 작성한 경우

이번에는 db 밑에 있는 설정값들을 타입을 지정해 가져와보겠습니다.

@Injectable()
export class MemberService {

    constructor(
        private configService: ConfigService<ConfigKey>
    ){
        const dbConfig: DbConfig = this.configService.get("db");
        console.log('환경변수 테스트', dbConfig.host);
        
    }

이런 방식으로 조금 더 안전하게 환경 변수를 활용할 수 있을 것 같습니다.

마찬가지로 db내에 존재하지 않는 키값을 입력했을 때 에러가 발생하는 것을 확인할 수 있습니다.

이런식으로 타입을 지정하면 키값이 수정되었을 때 interface만 수정해주면 되고, 컴파일 시점에 에러를 발견할 수 있으니 이런 방식으로 활용하는게 좋을 것 같습니다.

7. 컴파일 설정

여기서 시간을 꽤 잡아먹었는데 공식 문서를 꼼꼼히 확인하지 않았네요.

기본적으로 nestjs에서는 ts파일 같은 동적 파일은 컴파일을 지원하지만 정적파일의 경우 별도로 dist파일로 컴파일을 하거나 하지 않습니다.
대신 nest-cli.json에서 아래와 같이 설정해줍니다.

  "compilerOptions": {
    "assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}],
    "watchAssets": true,
    "deleteOutDir": true
  }

8. 실행 환경에 따른 환경변수 설정

이제 실행 환경에 따라 환경변수를 별도로 설정해보겠습니다.

  • 스크립트 수정 package.json
    "start:dev": "cross-env NODE_ENV=development nest start --watch",
    "start:test": "cross-env NODE_ENV=test nest start --watch",

기존에 있던 start:dev 스크립트를 수정하고, 추가로 테스트를 위한 start:test 스크립트를 작성했습니다.

  • NODE_ENV=development
    NODE_ENV=test
    3번 항목에서 환경변수를 로딩할 때 지정한 값이 여기서 입력하는 값입니다.

이제 각 실행환경을 테스트 해보면

  • start:dev

  • start:test

각 실행환경에 따라 다른 값이 지정된 것을 확인할 수 있습니다.

참고문서 : NestJS-Configuration

profile
꾸준히 하자!

0개의 댓글