DEV Community

Radek
Radek

Posted on

Managing Environment Variables in NestJS: A Guide to Custom Configurations

When developing applications with NestJS, managing environment variables efficiently is crucial for ensuring different configurations for development, staging, and production environments. In this blog post, we'll delve into setting up custom environment configurations in NestJS, focusing on the manage multiple environment, validation and accessing configuration

1. Before start

  • install @nestjs/config
  • install joi - for validation env

2. Setting Up the CustomConfigModule

Go to the src and create config folder and in it config.module.ts. The CustomConfigModule is a crucial part of this setup, it imports and configures the ConfigModule from @nestjs/config. Here's a quick overview:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { configValidationSchema } from './config.schema';
import { CustomConfigService } from './config.service';

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: `${process.cwd()}/env/.env.${process.env.NODE_ENV}`,
      validationSchema: configValidationSchema,
      isGlobal: true,
      cache: true,
    }),
  ],
  providers: [CustomConfigService],
  exports: [CustomConfigService],
})
export class CustomConfigModule {}
Enter fullscreen mode Exit fullscreen mode

This module dynamically sets the path to the environment file based on the NODE_ENV variable and uses configValidationSchema for validation.

3. Validating Environment Variables

Validation is key to ensuring that your environment variables are set correctly. Create config.schema.ts in config folder. I use Joi to validate and set defaults for these variables:

import * as Joi from 'joi';

export const configValidationSchema = Joi.object({
  NODE_ENV: Joi.string()
    .valid('development', 'staging', 'production')
    .default('development'),
  PORT: Joi.number().default(3000),
});
Enter fullscreen mode Exit fullscreen mode

This schema ensures that NODE_ENV is one of the specified strings and sets a default port if none is provided. Of course you can add as many env variables as you want eg. for database connection.

4. Accessing Configurations through CustomConfigService

To have nice intellisense and possibility to group our env variables I create CustomConfigService, defined in config/config.service.ts, is an injectable service that wraps the standard ConfigService:

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class CustomConfigService {
  constructor(private readonly configService: ConfigService) {}

  get app() {
    return {
      nodeEnv: this.configService.get<string>('NODE_ENV'),
      port: this.configService.get<number>('PORT'),
    };
  }
}

Enter fullscreen mode Exit fullscreen mode

This service simplifies accessing the configured variables throughout your application.

5. Integrating with the Application

To utilize this configuration setup, you need to import CustomConfigModule in your app.module.ts. This makes the configurations and validations defined in the module available application-wide.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CustomConfigModule } from './config/config.module';

@Module({
  imports: [CustomConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

6. Modifying the Start Script

Finally, modify the start script in package.json to include the NODE_ENV variable:

"scripts": {
  "start": "NODE_ENV=development nest start"
}
Enter fullscreen mode Exit fullscreen mode

This ensures that the application uses the correct environment settings when you start your NestJS app.

Conclusion

Setting up custom environment configurations in NestJS can seem daunting initially, but with the right setup, like the CustomConfigModule, configValidationSchema, and CustomConfigService, you can ensure that your application runs smoothly in different environments. This setup not only promotes cleaner code but also enhances the overall maintainability of your application.

Top comments (0)