Progressive Full Stack Application Development with Live Projects

Nest JS

Managing Environments in Nest JS

In Node.js, the “environment” refers to the runtime environment of your application, which can have different configurations and variables depending on the context (e.g., development, testing, production). Environment variables are used to store configuration values, secrets, and other settings that can vary depending on the environment your application is running in.

In a NestJS application, managing environment variables and configurations is crucial for keeping your code flexible and secure. Let’s break down how to handle it in a NestJS application.

1. Using .env Files

NestJS uses environment variables through the .env file, which typically stores key-value pairs for various configuration settings. This file is usually located at the root of your project and contains variables like

				
					DATABASE_URL=postgres://user:password@localhost:5432/dbname
JWT_SECRET=mysecretkey
PORT=3000
NODE_ENV=development

				
			

These environment variables can be accessed in your code through process.env

2. Using @nestjs/config for Configuration Management

NestJS provides the @nestjs/config package, which is a wrapper around dotenv and allows easy management of environment variables and configurations in a structured way.

Step-by-Step Guide to Manage Environment Variables

Step 1: Install Necessary Packages

First, you need to install the @nestjs/config and dotenv packages. You can install them via npm:

				
					npm install @nestjs/config dotenv

				
			
Step 2: Create a .env File

At the root of your NestJS project, create a .env file where you can store environment variables.

				
					# .env file example
PORT=3000
DATABASE_URL=postgres://user:password@localhost:5432/dbname
JWT_SECRET=mysecretkey
NODE_ENV=development

				
			
Step 3: Configure @nestjs/config in your AppModule

Next, configure the ConfigModule to read the .env file and make environment variables available throughout your application.

In your app.module.ts, import and configure the ConfigModule

				
					import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { YourModule } from './your.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,  // Makes the config accessible throughout the app
      envFilePath: '.env',  // Specifies the path to the .env file
    }),
    YourModule,
  ],
})
export class AppModule {}

				
			

The isGlobal: true option makes the configuration available globally in the entire application.

Step 4: Accessing Environment Variables in Services/Controllers

You can now inject the ConfigService into your services or controllers to access the environment variables.

For example, in a service:

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

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

  getPort(): string {
    return this.configService.get('PORT');  // Access environment variable
  }

  getDatabaseUrl(): string {
    return this.configService.get('DATABASE_URL');
  }
}

				
			

Here, this.configService.get('PORT') retrieves the PORT variable from the .env file.

				
					import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { YourModule } from './your.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,  // Makes the config accessible throughout the app
      envFilePath: '.env',  // Specifies the path to the .env file
    }),
    YourModule,
  ],
})
export class AppModule {}

				
			
Step 5: Use Environment Variables for Conditional Logic

You can also use environment variables to adjust your application’s behavior depending on the environment (e.g., development, production).

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

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

  getDatabaseConnection() {
    const dbUrl = this.configService.get('DATABASE_URL');
    if (this.configService.get('NODE_ENV') === 'production') {
      // production-specific logic
      console.log('Running in production mode');
    }
    return dbUrl;
  }
}

				
			

3. Managing Multiple Environments

You can have different .env files for different environments, such as .env.development, .env.production, etc.

To load the right file based on the environment, you can modify the ConfigModule setup as follows:

				
					ConfigModule.forRoot({
  envFilePath: `.env.${process.env.NODE_ENV}`,  // Dynamically load based on NODE_ENV
  isGlobal: true,
});

				
			

For example, when NODE_ENV is set to “production”, it will load the .env.production file.

4. Using Config Validation (Optional but Recommended)

To ensure that all the necessary environment variables are set correctly, you can validate them using Joi or any other validation library. You can create a validation schema for your configuration.

First, install @hapi/joi (Joi):

				
					npm install @hapi/joi

				
			

Then, create a validation schema

				
					import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from '@hapi/joi';

ConfigModule.forRoot({
  validate: (config: Record) => {
    const schema = Joi.object({
      PORT: Joi.number().required(),
      DATABASE_URL: Joi.string().uri().required(),
      JWT_SECRET: Joi.string().required(),
      NODE_ENV: Joi.string().valid('development', 'production').required(),
    });

    const { error } = schema.validate(config);
    if (error) {
      throw new Error(`Configuration validation error: ${error.message}`);
    }
    return config;
  },
  isGlobal: true,
});

				
			

This will ensure that the required environment variables are set and validated when the application starts.

Summary of Key Concepts

  • .env File: A file where you store environment variables.
  • @nestjs/config: A NestJS package to manage configuration and environment variables.
  • ConfigService: A service that allows you to retrieve environment variables in a structured way.
  • Validation: Optional but important, using a library like Joi to ensure that all environment variables are set correctly.

By managing your environment variables this way, you can ensure that your application behaves differently based on the environment it is deployed in, and you can keep sensitive information like API keys and database credentials out of your codebase.