Deploy NestJS on AWS
Deploy your NestJS applications to AWS using Thunder patterns. This guide covers both serverless Lambda deployment and containerized service options.
There are two deployment patterns available for NestJS on AWS:
- Lambda — Deploy NestJS API endpoints using AWS Lambda and API Gateway with the
Lambdaconstruct - Containerized Service — Deploy containerized NestJS applications using ECS Fargate with the
Fargateconstruct
Lambda Deployment
Deploy NestJS applications to AWS Lambda and API Gateway using the Lambda construct. This pattern is ideal for API endpoints, serverless functions, and event-driven architectures.
Create Project
npm create nestjs@latest my-nestjs-appcd my-nestjs-apppnpm create nestjs my-nestjs-appcd my-nestjs-appbun create nestjs my-nestjs-appcd my-nestjs-appInstall Dependencies and Setup Stack
npm i tsx @thunder-so/thunder @vendia/serverless-express --save-devpnpm add -D tsx @thunder-so/thunder @vendia/serverless-expressbun add -d tsx @thunder-so/thunder @vendia/serverless-expressCreate Lambda Handler
Create a Lambda handler file to bootstrap your NestJS application:
import { NestFactory } from '@nestjs/core';import { AppModule } from './app.module';import { configure } from '@vendia/serverless-express';
let cachedServer;
async function bootstrapServer() { if (!cachedServer) { const app = await NestFactory.create(AppModule); await app.init(); const expressApp = app.getHttpAdapter().getInstance(); cachedServer = configure({ app: expressApp }); } return cachedServer;}
export const handler = async (event, context) => { const server = await bootstrapServer(); return server(event, context);};Setup Stack
import { Cdk, Lambda, type LambdaProps } from "@thunder-so/thunder";
const fnProps: LambdaProps = { env: { account: 'your-account-id', region: 'us-east-1' }, application: 'your-application-id', service: 'your-service-id', environment: 'production',
functionProps: { codeDir: 'dist', handler: 'lambda.handler', include: [ 'node_modules', 'lambda.js', ], exclude: ['node_modules/.npmignore', '**/*.ts', '**/*.map'], },};
new Lambda( new Cdk.App(), `${fnProps.application}-${fnProps.service}-${fnProps.environment}-stack`, fnProps);Deploy
Before you deploy, run your build script to generate artifacts in the dist directory.
npm run buildnpx cdk deploy --all --app="npx tsx stack/index.ts"pnpm run buildpnpm exec cdk deploy --all --app="pnpm exec tsx stack/index.ts"bun run buildnpx cdk deploy --all --app="bunx tsx stack/index.ts"When the deployment is complete, you will see the API Gateway URL in the output. You can access your NestJS app at that URL.
Containerized Service Deployment
Deploy containerized NestJS applications using ECS Fargate and Application Load Balancer with the Fargate construct. This pattern is ideal for long-running services, full-stack applications, and when you need persistent connections or WebSocket support.
Install Dependencies and Setup Stack
npm i tsx @thunder-so/thunder --save-devpnpm add -D tsx @thunder-so/thunderbun add -d tsx @thunder-so/thunderimport { Cdk, Fargate, type FargateProps } from "@thunder-so/thunder";
const svcProps: FargateProps = { env: { account: 'your-account-id', region: 'us-west-2' }, application: 'your-application-id', service: 'your-service-id', environment: 'production',
rootDir: '', // e.g. 'app' for monorepos};
new Fargate( new Cdk.App(), `${svcProps.application}-${svcProps.service}-${svcProps.environment}-stack`, svcProps);Build Settings Using Nixpacks
Configure automatic containerization with Nixpacks:
const svcProps: FargateProps = { // ... other props
buildProps: { buildSystem: 'Nixpacks', installcmd: 'npm install', buildcmd: 'npm run build', startcmd: 'npm run start:prod', },};Build Settings Using Docker Container
Alternatively, use a custom Dockerfile:
FROM public.ecr.aws/docker/library/node:20-alpine AS base
FROM base AS builderWORKDIR /app
COPY package*.json ./RUN npm ci
COPY . .RUN npm run build
FROM base AS runnerWORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCOPY package.json ./
EXPOSE 3000
CMD ["node", "dist/main"]const svcProps: FargateProps = { // ... other props
serviceProps: { dockerFile: 'Dockerfile', port: 3000, },};Environment Variables and Secrets
Configure runtime environment variables and secrets:
const svcProps: FargateProps = { // ... other props
serviceProps: { variables: [ { NODE_ENV: 'production' }, { API_URL: 'https://api.example.com' } ], secrets: [ { key: 'DATABASE_URL', resource: 'arn:aws:secretsmanager:us-west-2:123456789012:secret:/my-app/DATABASE_URL-abc123' }, ], },};Deploy
Build and deploy your containerized application:
npm run buildnpx cdk deploy --all --app="npx tsx stack/index.ts"pnpm run buildpnpm exec cdk deploy --all --app="pnpm exec tsx stack/index.ts"bun run buildnpx cdk deploy --all --app="bunx tsx stack/index.ts"After deployment, you’ll receive an Application Load Balancer URL to access your containerized NestJS application.