How to Run a NestJS App on a Custom Port

Updated: January 1, 2024 By: Guest Contributor Post a comment

Introduction

NestJS is a popular framework for building efficient and scalable Node.js server-side applications. By default, a NestJS application runs on port 3000, but it’s common to change this default to cater to various deployment environments or to avoid port conflicts. This guide will show you how to run your NestJS app on a custom port, covering basic usage as well as more advanced scenarios.

Setting the Port in Code

To run your NestJS app on a custom port, the first and most straightforward method is to set it within your application code. Locate the file where you bootstrap your NestJS application, typically main.ts, and set the desired port using the listen() method.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3001);
}
bootstrap();

With this change, your application will now start on port 3001 instead of the default port 3000.

Using Environment Variables

It’s a good practice to manage configurations such as port numbers using environment variables. Create a .env file at the root of your project and define a new variable named PORT:

PORT=3001

Then, modify your bootstrapping code to read the port number from the environment variable:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv';

dotenv.config();

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const port = process.env.PORT || 3000;
  await app.listen(port);
  console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();

This configuration allows your application to default to port 3000 if the PORT variable is not defined, providing flexibility across different environments.

To load environment variables dynamically during application startup, you can also integrate the @nestjs/config package:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);
  const port = configService.get('PORT') || 3000;
  await app.listen(port);
  console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();

In this example, you’ll need to import the @nestjs/config module inside the app.module.ts to make it available throughout your application:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}

Command Line Arguments

Another method for specifying a custom port is through command line arguments when starting the NestJS application. Below is an example of how you might use command-line arguments with NestJS:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const portArgIndex = process.argv.indexOf('--port');
  const port = portArgIndex >= 0 ? process.argv[portArgIndex + 1] : 3000;
  await app.listen(port);
}
bootstrap();

You can then start the NestJS server with `node dist/main.js –port 3001` where `dist/main.js` is the compiled JavaScript file corresponding to your `main.ts` and `3001` is the desired custom port.

Integrating with Package Managers

Many developers use package managers like `npm` or `yarn` for starting their applications. To integrate a custom port with `npm start`, you can modify the `start` script in your `package.json` file as follows:

{
  "scripts": {
    "start": "nest start --port 3001"
  }
}

Use environmental variables to keep it dynamic:

{
  "scripts": {
    "start": "PORT=3001 nest start"
  }
}

By adjusting the start script, your application will start on the specified port without additional code changes every time you issue the `npm start` command.

Dealing with Docker

In a containerized environment such as Docker, port management is very crucial. You can pass an environment variable to a Dockerized NestJS app to tell it which port to listen on by updating the `Dockerfile`:

...other dockerfile configurations...

ENV PORT 3001

...remaining dockerfile configurations...

And when running the Docker image, bind the internal port to an external one:

docker run -p 8080:3001 my-nestjs-app

In this command, Docker binds port 3001 inside the container to port 8080 on the host system.

Advanced Applications with Multiple Ports

Sometimes, advanced applications may require running on multiple ports for different purposes such as serving HTTP and WebSocket traffic separately. This can be achieved by creating additional server instances:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { INestApplication, ExpressAdapter } from '@nestjs/platform-express';
import * as express from 'express';

async function bootstrap() {
  const server = express();
  const app: INestApplication = await NestFactory.create(AppModule, new ExpressAdapter(server));

  await app.init();

  const httpServer = server.listen(3001);
  const wsServer = server.listen(3002);

  console.log(`HTTP Server running on port 3001`);
  console.log(`WebSocket Server running on port 3002`);
}
bootstrap();

This code utilizes the `INestApplication` and `ExpressAdapter` interfaces to create two server instances running on different ports. Keep in mind that advanced configurations like this also require a deeper understanding of both NestJS and the underlying HTTP server system.

Conclusion

Running your NestJS application on a custom port can be achieved effortlessly with a few code changes or configuration adjustments. The technique used to set a custom port can vary based on the environment and architectural requirements ranging from simple one-line code changes to integration with Docker or even multiple port assignments. Ultimately, NestJS provides the flexibility necessary to accommodate your application’s port requirements efficiently. Use these methods responsibly, and always consider the best practices for configuration management.