How to Properly Run your NestJS Server in Cluster-Mode

Radovan Stevanovic
Enlear Academy
Published in
2 min readJan 29, 2020

--

Photo by James Harrison on Unsplash

If you have a Node.js application, and it is about to be or has already been shipped to production, chances are you need to run it in cluster mode!

First of all, let’s go through the basic needs of our project. Imagine that you have some API written in NestJS and you want to run it in cluster mode as you should. And also, for sake of this conversation, let’s assume that as with every project so far, your project needs to be able to expand by adding new microservices from your mono-repo code base.

Step 1 — Create ConfigService

First, we should create ConfigService as it will be the one place from which we provide configuration to our app.

import * as dotenv from 'dotenv';
import * as fs from 'fs';

export class ConfigService {
private readonly envConfig: Record<string, string> = dotenv.parse(fs.readFileSync('.env'));

get(key): string {
return this.envConfig[key];
}

static getENV() {
return dotenv.parse(fs.readFileSync('.env'));
}

static isDevEnvironment(): boolean {
return ConfigService.getENV().ENVIRONMENT === 'DEV';
}
}

Step 2— Abstract Clusterization Logic

Now, we want to abstract our clusterization logic to some service so we can use it in multiple microservices.

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

import * as cluster from 'cluster';
import * as os from 'os'

const numCPUs = os.cpus().length;

@Injectable()
export class ClusterService {
static clusterize(callback: Function): void {
if (cluster.isMaster && !ConfigService.isDevEnvironment()) {
console.log(`MASTER SERVER (${process.pid}) IS RUNNING `);

for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}

cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
callback();
}
}
}

Step 3 — Finalizing Things

Now, the only thing that is left for us to do is to actually call this method in the right place.

import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import * as bodyParser from 'body-parser';

import { ClusterService, ConfigService } from '@services';
import { AssetsUploadModule } from './assets-upload.module';

async function bootstrap() {
const port = ConfigService.getENV().UPLOAD_SERVICE_PORT;

const app = await NestFactory.create(AssetsUploadModule);
app.use(bodyParser.json({ limit: '500mb' }));
app.enableCors();
app.useGlobalPipes(new ValidationPipe());
await app.listen(port);
console.log(`SERVER (${process.pid}) IS RUNNING ON `, port);
}

ClusterService.clusterize(bootstrap);

And that is that how our node process will run in cluster mode if the environment is the production. And of course, for every new service, we just run the clusterize method and we are good to go!

Thank you for Reading !!!

--

--

Curiosity in functional programming, cybersecurity, and blockchain drives me to create innovative solutions and continually improve my skills