Deploying a NestJS Application

From Local to Production

Deploying a NestJS Application

This is a continuation of the NestJS series, take a look at part 1 here

Here we'll cover:

  • Setting up NestJS app

  • Dockerizing your NestJS app

  • Deploying to various platforms

  • Using Nginx

  • Other Deployment methods

Why Deploying

Deploying an app can both be an easy and a difficult task depending on the platform you deploying to and if you've CI/CD pipelines set up. I'll cover the CI/CD pipeline setup with NestJS in another article. I'm going to summarise how to deploy a Nestjs app to the common platforms with the common ways

Step 1: Setting Up Your NestJS Application

Before we can deploy our application, let’s ensure we have a basic NestJS app set up. Take a look at NestJS 101 to get started on a simple REST API. If you don’t already have one, you can create it using the NestJS CLI:

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

Step 2: Dockerizing Your NestJS Application

Dockerizing your application helps in creating a consistent environment across development, testing, and production.

Create a Dockerfile

At the root of your project, create a Dockerfile with the following content:

# If you've things like migrations, ssl config, orm, etc use builder
# e.g. FROM node:20.9 as builder
# RUN yarn prisma:gen  && yarn build backend

# Use the official Node.js image as the base image
FROM node:20.9 as runtime

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json or yarn.lock
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the NestJS application
RUN npm run build

# Expose the port the app runs on
EXPOSE 3000

# Define the command to run the application
CMD node ./main.js

Create a .dockerignore file

Create a .dockerignore file to exclude unnecessary files from the Docker build context:

node_modules
dist
npm-debug.log
Dockerfile
.dockerignore

Build and Run the Docker Image

Build the Docker image:

docker build -t my-nestjs-app .

Run the Docker container:

docker run -p 3000:3000 my-nestjs-app

Your application should now be running inside a Docker container and accessible at http://localhost:3000. Using a platform that supports orchestration, you can manage docker images there to expose to external users

Step 3: Deploy Apps to Various Platforms

1. AWS (Amazon Web Services)

Install AWS CLI to make it efficient in managing was resources

# install & setup
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

# configure
aws configure
  1. Using Elastic Beanstalk

Elastic Beanstalk is a PaaS that simplifies the process of deploying applications to AWS. It makes it easier to deploy and manage applications in the cloud without worrying about the infrastructure that runs those applications. Elastic Beanstalk automatically handles the deployment, from capacity provisioning, load balancing, and auto-scaling to application health monitoring.

  • Install the Elastic Beanstalk CLI: Use brew or pip

  •   brew install awsebcli
    
  • Initialize your Elastic Beanstalk application:

      eb init -p node.js my-nestjs-app
    
  • Create an environment and deploy your application:

      eb create my-nestjs-env
      eb deploy
    
  • Access deployed app

eb list 
eb status your_env
  1. Using ECS (Elastic Container Service) and ECR (Elastic Container Registry)

ECS is a fully managed container orchestration service that makes it easy to run, stop, and manage Docker containers on a cluster of Amazon EC2 instances. ECS can be used to deploy and manage containerized applications.

Amazon Elastic Container Registry (ECR) is a fully managed Docker container registry that makes it easy for developers to store, manage, and deploy Docker container images.

  • Push Your Docker Image to ECR:

    • Authenticate Docker to your Amazon ECR registry.

    • Create a repository in Amazon ECR.

    • Tag your Docker image and push it to the repository.

    aws ecr get-login-password --region your-region | docker login --username AWS --password-stdin your-account-id.dkr.ecr.your-region.amazonaws.com
    docker tag my-nestjs-app:latest your-account-id.dkr.ecr.your-region.amazonaws.com/my-nestjs-app:latest
    docker push your-account-id.dkr.ecr.your-region.amazonaws.com/my-nestjs-app:latest
  • Set Up ECS:

    • Create a new ECS cluster.

    • Define a task definition that uses your Docker image from ECR.

    • Create a service that runs your task definition on your ECS cluster.

aws ecs update-service --cluster $CLUSTER_NAME --service $SERVICE_NAME --force-new-deployment
aws ecs update-service --cluster $CLUSTER_NAME --service $SERVICE_NAME --force-new-deployment

Access the deployed app URL using the public URL from the ECS task definition

2. Heroku

Heroku is a cloud platform that simplifies deploying applications.

  • Install the Heroku CLI:

      curl https://cli-assets.heroku.com/install.sh | sh
    
  • Log in to Heroku and Create a New App:

      heroku login
      heroku create my-nestjs-app
    
  • Deploy Your Application:

    • Add a Procfile to the root of your project specifying how to run your app.

        web: npm run start:prod
      
    • Commit your changes and push to Heroku.

        git add .
        git commit -m "Deploy to Heroku"
        git push heroku main
      

3. Render

Render is one of my favorite to deploy my personal apps. Render is a simple yet powerful platform for deploying applications. It's a modern cloud platform that simplifies the process of deploying applications, databases, and static sites. It offers a variety of features and services that make it easy to deploy and manage applications with minimal configuration.

  1. Create a render.yaml file in your project:

     services:
       - type: web
         name: my-nestjs-app
         env: node
         plan: free
         buildCommand: npm install && npm run build
         startCommand: npm run start:prod
    
  2. Commit the file and push it to your Git repository.

  3. Connect your Git repository to Render and deploy.

4. Digital Ocean

Digital Ocean is a cloud infrastructure provider that offers a range of cloud services to help developers deploy, manage, and scale applications quickly and efficiently. DigitalOcean provides virtual private servers (called Droplets), managed databases, object storage, Kubernetes clusters, and various other services.

Using App Platform

  1. Create a new app on the Digital Ocean App Platform.

  2. Connect your Git repository.

  3. Set the build and run commands

  4. Deploy your application.

Using Droplets with Docker

  1. Create a Droplet and install Docker.

  2. Push your Docker image to Docker Hub.

  3. Pull the Docker image on your Droplet and run it.

Step 4: Using Nginx for Deployment

Nginx is a high-performance web server, reverse proxy server, and load balancer. It is known for its stability, rich feature set, simple configuration, and low resource consumption. Nginx is commonly used to serve static content, as well as to proxy dynamic content requests to other servers.

Nginx can be used as a reverse proxy to serve the NestJS application.

Configuring Nginx

Create an Nginx configuration file (e.g., nestjs.conf):

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Deploy Nginx and Your Application

  1. Install Nginx on your server.

  2. Copy your configuration file to /etc/nginx/conf.d/.

  3. Restart Nginx:

     sudo systemctl restart nginx
    
  4. Ensure your NestJS application is running and listening on port 3000.

Step 5: Other Deployment Methods

Using PM2

PM2 is a process manager for Node.js applications that helps keep your application alive forever and provides an easy way to manage processes.

  1. Install PM2 globally:

     npm install -g pm2
    
  2. Start your application with PM2:

     pm2 start dist/main.js --name my-nestjs-app
    
  3. Save the PM2 process list and configure it to start on boot:

     pm2 save
     pm2 startup
    

There are some other ways to deploy NestJS apps that I haven't covered e.g. GCP, Azure, On-Prem, windows server, etc. These are just the most common ways I've interacted and worked with. If there's any you would love to chat about, please leave a comment here, am looking forward to learning more

Did you find this article valuable?

Support Nicanor Talks Web by becoming a sponsor. Any amount is appreciated!