Back to Blog
Tutorial

How to Deploy a NestJS Application in 1 Minute

Daniel Brooks5 min read
How to Deploy a NestJS Application in 1 Minute

NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. Built with TypeScript by default, it combines elements of object-oriented programming, functional programming, and functional reactive programming. Deploying NestJS to production requires proper TypeScript compilation, build configuration, and server setup.

With Out Plane, you can deploy your NestJS application in under a minute. This guide shows you exactly how.

What You'll Need

Before starting, make sure you have:

  • Node.js 20+ installed on your machine
  • npm (comes with Node.js)
  • A GitHub account
  • A NestJS application in a GitHub repository

Don't have Node.js installed? Download it from nodejs.org:

  • Windows: Download the LTS installer from nodejs.org
  • macOS: Use brew install node or download from nodejs.org
  • Linux: Run curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && sudo apt install -y nodejs (Ubuntu/Debian)

Once Node.js is installed, create a new NestJS project:

bash
npx @nestjs/cli new my-nestjs-app
cd my-nestjs-app

If you don't have a NestJS app yet, use our example below.

Quick Start: Sample NestJS Application

Here's a minimal NestJS application you can use. Create a new project with the NestJS CLI:

bash
npx @nestjs/cli new my-nestjs-app
cd my-nestjs-app

The CLI generates a project with the following key files. Update them for production deployment.

Replace src/app.controller.ts:

typescript
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): { message: string; status: string } {
    return this.appService.getHello();
  }

  @Get('health')
  getHealth(): { status: string } {
    return { status: 'healthy' };
  }
}

Replace src/app.service.ts:

typescript
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): { message: string; status: string } {
    return {
      message: 'Hello from NestJS!',
      status: 'running',
    };
  }
}

Update src/main.ts to listen on the correct port and host:

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

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

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');

  console.log(`Application running on port ${port}`);
}
bootstrap();

The 0.0.0.0 host binding is required for the application to accept connections inside a container.

Create a Procfile in the project root (no file extension):

text
web: node dist/main.js

This tells Buildpacks how to start your compiled NestJS application.

Push this code to a GitHub repository, and you're ready to deploy.

Optional: Add a Dockerfile

If you prefer full control over the build process, create a Dockerfile with multi-stage builds for smaller images:

dockerfile
# Build stage
FROM node:20-alpine AS builder

WORKDIR /app

COPY package.json package-lock.json* ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage
FROM node:20-alpine

WORKDIR /app

ENV NODE_ENV=production

COPY package.json package-lock.json* ./
RUN npm ci --omit=dev

COPY --from=builder /app/dist ./dist

EXPOSE 8080

CMD ["node", "dist/main.js"]

This produces a lean production image with only compiled JavaScript and production dependencies. With a Dockerfile, select Dockerfile as your build method in the next step. Without one, select Buildpacks and Out Plane handles everything automatically.

Deploy in 3 Steps

Step 1: Connect Your Repository

  1. Go to console.outplane.com
  2. Sign in with your GitHub account
  3. Select your NestJS repository from the list

Out Plane automatically detects your Node.js application and configures the build process.

Step 2: Configure Your Application

Configure the following settings in the create application form:

Build Method

Select how Out Plane should build your application:

  • Buildpacks (Recommended): Automatically detects Node.js, installs dependencies, runs npm run build, and starts the application using your Procfile. No additional configuration needed.
  • Dockerfile: Use this if you have a custom Dockerfile in your repository for full control over the build process.

For most NestJS applications, Buildpacks is the easiest option.

Basic Settings

  • Port: Set to 8080
  • Branch: Select main or your preferred branch
  • Region: Choose the region closest to your users

Environment Variables (Optional)

If your application uses environment-specific configuration, add them here. For our simple example, no environment variables are required.

For more complex applications, you might add variables like database URLs or API keys using the Add button or Raw Edit for bulk entry:

text
DATABASE_URL=postgres://user:password@host/database
JWT_SECRET=your-jwt-secret
NODE_ENV=production

Step 3: Deploy

Click Deploy Application and watch the build process:

  1. Queued → Waiting for resources
  2. Building → Installing dependencies, compiling TypeScript
  3. Deploying → Starting your NestJS application
  4. Ready → Your app is live

Once the status shows Ready, your application is live. You can find your application URL at the top of the deployment page. Click the URL to open your NestJS app in a new tab. SSL is automatically configured.

Production Best Practices

Enable CORS

Configure Cross-Origin Resource Sharing for frontend applications:

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

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

  app.enableCors({
    origin: process.env.CORS_ORIGIN || '*',
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
    credentials: true,
  });

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');
}
bootstrap();

Use Helmet for Security Headers

Install and configure Helmet to set secure HTTP headers:

bash
npm install helmet
typescript
import helmet from 'helmet';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(helmet());

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');
}
bootstrap();

Enable Compression

Reduce response sizes with compression middleware:

bash
npm install compression @types/compression
typescript
import * as compression from 'compression';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(compression());

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');
}
bootstrap();

Global Validation Pipes

Use class-validator to automatically validate incoming request data:

bash
npm install class-validator class-transformer
typescript
import { ValidationPipe } from '@nestjs/common';

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

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      forbidNonWhitelisted: true,
      transform: true,
    }),
  );

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');
}
bootstrap();

Proper Logging

Use the built-in NestJS logger for structured production logs:

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: ['error', 'warn', 'log'],
  });

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');

  Logger.log(`Application running on port ${port}`, 'Bootstrap');
}
bootstrap();

Connecting a Database

Most NestJS applications need a database. Out Plane provides managed PostgreSQL:

  1. Go to Databases in the sidebar
  2. Click Create Database
  3. Select PostgreSQL version and region
  4. Copy the connection URL

Add the connection URL as an environment variable:

text
DATABASE_URL=postgres://user:password@host:5432/database

Using TypeORM

Install TypeORM and the PostgreSQL driver:

bash
npm install @nestjs/typeorm typeorm pg

Configure TypeORM in your app.module.ts:

typescript
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      url: process.env.DATABASE_URL,
      autoLoadEntities: true,
      synchronize: false,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Set synchronize: false in production. Use migrations instead to manage schema changes safely.

Using Prisma

Alternatively, use Prisma with NestJS:

bash
npm install prisma @prisma/client
npx prisma init

Create a Prisma service:

typescript
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService
  extends PrismaClient
  implements OnModuleInit, OnModuleDestroy
{
  async onModuleInit() {
    await this.$connect();
  }

  async onModuleDestroy() {
    await this.$disconnect();
  }
}

Register the service in your module and inject it wherever you need database access.

Custom Domain Setup

Replace the default .outplane.app URL with your own domain:

  1. Navigate to Domains
  2. Click Map Domain
  3. Enter your domain (e.g., api.yourdomain.com)
  4. Add the DNS records shown to your domain registrar

SSL certificates are automatically provisioned once DNS propagates.

Monitoring Your Application

After deployment, monitor your NestJS application:

  • Logs: View real-time application logs including NestJS bootstrap and request logs
  • Metrics: Track CPU, memory, and network usage
  • HTTP Logs: Analyze incoming requests, response times, and status codes

Access these from the sidebar in your application dashboard.

Troubleshooting

Build Fails with TypeScript Errors

Fix compilation errors before deploying. Run npm run build locally to verify your TypeScript compiles without errors. Check tsconfig.build.json for correct compiler settings.

Application Won't Start

Check the port configuration. Make sure you set the port to 8080 in the application settings. Your main.ts should read process.env.PORT and bind to 0.0.0.0.

Module Resolution Errors

Verify all dependencies are in package.json. NestJS uses dependency injection extensively. Missing providers or imports cause runtime errors. Check your application logs for the specific module that failed to resolve.

typescript
// Common error: forgot to import a module
@Module({
  imports: [TypeOrmModule.forFeature([User])], // Must import entity modules
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}

Memory Issues

Adjust Node.js memory limits. If your application runs out of memory during build or runtime, set the NODE_OPTIONS environment variable:

text
NODE_OPTIONS=--max-old-space-size=512

For large applications with many modules, increase this value as needed.

Swagger Docs Not Accessible

Ensure Swagger is configured before listen. If you use @nestjs/swagger, make sure the setup runs before app.listen():

typescript
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

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

  const config = new DocumentBuilder()
    .setTitle('My API')
    .setVersion('1.0')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api/docs', app, document);

  const port = process.env.PORT || 8080;
  await app.listen(port, '0.0.0.0');
}
bootstrap();

Access your API documentation at https://your-app.outplane.app/api/docs.

Next Steps

Your NestJS application is now deployed and running in production. Here's what to explore next:

  • Scale your application: Adjust instance types and auto-scaling settings for higher traffic
  • Set up CI/CD: Enable automatic deployments on every git push
  • Add monitoring: Integrate with external monitoring tools via Out Plane's metrics export
  • Build microservices: Use NestJS microservice transporters with Out Plane's internal networking

Summary

Deploying a NestJS application to Out Plane takes three steps:

  1. Connect your GitHub repository
  2. Configure port (8080), environment variables, and build method
  3. Deploy and get your live URL with automatic HTTPS

No server configuration, no manual SSL setup, no infrastructure management. Full support for TypeScript compilation, dependency injection, and modular architecture.

Ready to deploy your NestJS application? Get started with Out Plane and receive $20 in free credit.


Tags

nestjs
nodejs
typescript
deployment
tutorial
api

Start deploying in minutes

Connect your GitHub repository and deploy your first application today. $20 free credit. No credit card required.