Skip to main content

Deploy NestJS

This guide will help you deploy a NestJS application to Deployxa.

Overview

NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. Deployxa provides optimized deployments for NestJS with automatic configuration.

Features:

  • Automatic framework detection
  • TypeScript support
  • PostgreSQL, MySQL, MongoDB support
  • Automatic HTTPS
  • Global CDN
  • Zero configuration

Prerequisites

  • A NestJS application
  • A GitHub repository with your code
  • A Deployxa account

Quick Start

1. Create Your NestJS App

If you don't have a NestJS app yet:

npm i -g @nestjs/cli
nest new my-nestjs-app
cd my-nestjs-app

2. Push to GitHub

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/my-nestjs-app.git
git push -u origin main

3. Deploy to Deployxa

  1. Go to Deployxa Dashboard
  2. Click "New Project"
  3. Select your GitHub repository
  4. Deployxa will automatically detect NestJS
  5. Click "Deploy"

Your app will be live in under 60 seconds!

Configuration

Detected Settings

Deployxa automatically detects these settings:

SettingValue
FrameworkNestJS
Build Commandnpm run build
Output Directorydist
Start Commandnode dist/main.js
Port3000

Custom Configuration

If you need to customize settings:

  1. Go to ProjectSettingsBuild
  2. Modify settings as needed
  3. Save changes

Example Custom Settings:

{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"startCommand": "node dist/main.js"
}

Environment Variables

Adding Environment Variables

  1. Go to ProjectEnvironment
  2. Click "Add Variable"
  3. Enter key and value
  4. Click "Save"

Common NestJS Environment Variables:

NODE_ENV=production
PORT=3000
DATABASE_URL=postgresql://user:pass@host:5432/db
JWT_SECRET=your-jwt-secret

Using Environment Variables

In your NestJS app:

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

async function bootstrap() {
const app = await NestFactory.create(AppModule);
const port = process.env.PORT || 3000;
await app.listen(port);
}
bootstrap();
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
],
})
export class AppModule {}
// app.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

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

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

Database Configuration

Using PostgreSQL with TypeORM

npm install @nestjs/typeorm typeorm pg
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
url: configService.get<string>('DATABASE_URL'),
autoLoadEntities: true,
synchronize: false,
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}

Using MongoDB with Mongoose

npm install @nestjs/mongoose mongoose
// app.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
imports: [
ConfigModule.forRoot(),
MongooseModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
uri: configService.get<string>('MONGODB_URI'),
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}

Custom Domains

Adding a Custom Domain

  1. Go to ProjectDomains
  2. Click "Add Domain"
  3. Enter your domain (e.g., example.com)
  4. Configure DNS records
  5. Wait for verification

DNS Configuration

For Apex Domain (example.com):

Type: A
Name: @
Value: 76.76.21.21

For Subdomain (www.example.com):

Type: CNAME
Name: www
Value: cname.deployxa.com

Performance Optimization

Enable Clustering

Use Node.js clustering for better performance:

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cluster from 'cluster';
import * as os from 'os';

const numCPUs = os.cpus().length;

if ((cluster as any).isMaster) {
console.log(`Master process started with ${numCPUs} CPUs`);

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

(cluster as any).on('exit', (worker: any) => {
console.log(`Worker ${worker.process.pid} died`);
(cluster as any).fork();
});
} else {
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT || 3000);
}
bootstrap();
}

Enable Compression

npm install compression
// main.ts
import * as compression from 'compression';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(compression());
await app.listen(process.env.PORT || 3000);
}

Enable Caching

npm install @nestjs/cache-manager cache-manager
// app.module.ts
import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';

@Module({
imports: [
CacheModule.register({
ttl: 60, // seconds
max: 100, // maximum number of items in cache
}),
],
})
export class AppModule {}

Monitoring

Viewing Logs

  1. Go to ProjectLogs
  2. Select log type:
    • Build Logs: Deployment process
    • Runtime Logs: Application output
    • Error Logs: Application errors

NestJS Logging

Configure logging:

// main.ts
import { Logger } from '@nestjs/common';

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

const logger = new Logger('Bootstrap');
logger.log('Application started');

await app.listen(process.env.PORT || 3000);
}

Monitoring Metrics

  1. Go to ProjectAnalytics
  2. View metrics:
    • Request count
    • Response times
    • Error rates
    • Bandwidth usage
    • CPU/RAM usage

Health Checks

Deployxa automatically monitors your application:

  • HTTP health checks every 30 seconds
  • Automatic restart on failure
  • Alerts on consecutive failures

Add a health check endpoint:

// health.controller.ts
import { Controller, Get } from '@nestjs/common';

@Controller('health')
export class HealthController {
@Get()
healthCheck() {
return { status: 'healthy' };
}
}

Troubleshooting

Application Crashes on Start

Problem: Application crashes immediately

Solution:

  1. Check runtime logs for errors
  2. Verify environment variables
  3. Check for missing dependencies
  4. Ensure main.ts exists and is correct
  5. Check PORT configuration

Database Connection Failed

Problem: Cannot connect to database

Solution:

  1. Verify DATABASE_URL is correct
  2. Check database host and port
  3. Ensure database exists
  4. Check firewall rules
  5. Verify database credentials

Module Not Found

Problem: Cannot find module '@nestjs/core'

Solution:

  1. Check package.json has the dependency
  2. Run npm install locally
  3. Commit and push changes
  4. Redeploy

Slow Response Times

Problem: Application responds slowly

Solution:

  1. Enable clustering
  2. Enable compression
  3. Use caching
  4. Optimize database queries
  5. Upgrade plan for more resources

Port Already in Use

Problem: Error: listen EADDRINUSE

Solution:

  • Deployxa automatically handles port configuration
  • Ensure your code uses process.env.PORT or defaults to 3000

Best Practices

Project Structure

my-nestjs-app/
├── src/
│ ├── app.module.ts
│ ├── app.controller.ts
│ ├── app.service.ts
│ ├── main.ts
│ └── modules/
│ └── users/
│ ├── users.module.ts
│ ├── users.controller.ts
│ └── users.service.ts
├── test/
├── .env.example
├── nest-cli.json
├── tsconfig.json
├── package.json
└── README.md

Environment Variables

  • Never commit .env file
  • Use .env.example as template
  • Rotate secrets regularly
  • Use different values per environment

Security

  • Keep dependencies updated
  • Use HTTPS only
  • Validate all inputs
  • Use parameterized queries
  • Enable CORS properly
  • Use helmet for security headers
  • Implement rate limiting

Performance

  • Enable clustering
  • Use compression
  • Implement caching
  • Optimize database queries
  • Use connection pooling
  • Enable keep-alive

Database

  • Use connection pooling
  • Index frequently queried columns
  • Use transactions for complex operations
  • Backup database regularly
  • Use TypeORM or Prisma for complex queries

Advanced Configuration

Custom Main Configuration

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import * as helmet from 'helmet';
import * as compression from 'compression';

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

// Security
app.use(helmet());

// Compression
app.use(compression());

// Validation
app.useGlobalPipes(new ValidationPipe());

// CORS
app.enableCors({
origin: process.env.FRONTEND_URL,
credentials: true,
});

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

RESTful API Structure

// users.controller.ts
import { Controller, Get, Post, Put, Delete, Body, Param } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}

@Get()
findAll() {
return this.usersService.findAll();
}

@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(id);
}

@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}

@Put(':id')
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return this.usersService.update(id, updateUserDto);
}

@Delete(':id')
remove(@Param('id') id: string) {
return this.usersService.remove(id);
}
}

Middleware

// logger.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`Request: ${req.method} ${req.url}`);
next();
}
}

Examples

Basic NestJS App

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

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

@Get()
getHello(): string {
return this.appService.getHello();
}
}
// app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
getHello(): string {
return 'Hello, Deployxa!';
}
}

REST API

// items.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';

@Controller('items')
export class ItemsController {
private items = [];

@Get()
findAll() {
return this.items;
}

@Post()
create(@Body() item: any) {
this.items.push(item);
return item;
}
}

With Database

// users.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

@Column()
email: string;
}
// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}

findAll(): Promise<User[]> {
return this.usersRepository.find();
}

create(user: User): Promise<User> {
return this.usersRepository.save(user);
}
}

Resources


Need Help? Contact support@deployxa.com or join our community Discord.