How to Dockerize NestJS

Evaluating Classification Models: Metrics, Techniques & Best Practices


Today, I’ll walk you through how to dockerize a NestJS application. This will help you package your app into a container that can run consistently across different environments. Let’s get started!



Step 1: Setting Up the Dockerfile

First, we need to create a Dockerfile in the root directory of your NestJS project. This file will contain instructions for building your Docker image.

Here’s what the basic Dockerfile might look like:

# Use Node.js version 20 as the base image
FROM node:20

# Set the working directory in the container
WORKDIR /usr/src/app

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

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Run the application
CMD ["node", "dist/main.js"]
Enter fullscreen mode

Exit fullscreen mode

This Dockerfile does the following:

  • Uses Node.js version 20 as the base image.
  • Sets the working directory to /usr/src/app.
  • Copies package.json and package-lock.json to the working directory.
  • Installs the dependencies using npm install.
  • Copies the rest of the application code into the container.
  • Builds the application using npm run build.
  • Specifies the command to run the application with node dist/main.js.

Create a .dockerignore file to exclude unnecessary files from the Docker image.

node_modules
npm-debug.log
dist
.git
.env
*.md
.gitignore
Enter fullscreen mode

Exit fullscreen mode



Step 2: Testing the Docker Container Locally

Now, let’s test our Docker image locally to make sure everything works as expected.

Build the Docker Image:

Open your terminal at the root of your project and run:

   docker build -t nest-app .
Enter fullscreen mode

Exit fullscreen mode

This command builds the Docker image and tags it with nest-app.

Run the Docker Container:

After building the image, you can run it with:

   docker run -p 3000:3000 nest-app
Enter fullscreen mode

Exit fullscreen mode

This command starts a new container from the nest-app image and maps port 3000 of the container to port 3000 on your local machine.

Verify the Application:

Open your web browser and go to http://localhost:3000. If everything is set up correctly, you should see your NestJS application running.



Step 3: Optimizing for Production

To optimize the Dockerfile for production, we’ll make a few changes to reduce the image size and improve security.

Use Alpine Node Images:

Alpine images are smaller and more efficient. Update the base image to:

   FROM node:20-alpine
Enter fullscreen mode

Exit fullscreen mode

Set NODE_ENV Environment Variable:

Set NODE_ENV to production to optimize the application for production:

   ENV NODE_ENV production
Enter fullscreen mode

Exit fullscreen mode

Use npm ci Instead of npm install:

npm ci is more reliable for automated environments like Docker builds. Replace RUN npm install with:

   RUN npm ci
Enter fullscreen mode

Exit fullscreen mode

Add USER Instruction:

Run the application as a non-root user for better security. Add this after installing dependencies:

   USER node
Enter fullscreen mode

Exit fullscreen mode

Use Multistage Builds:

Multistage builds allow you to create a smaller final image by separating the build and runtime environments. Here’s an example of a multistage Dockerfile:

   # Development stage
   FROM node:20-alpine AS development
   WORKDIR /usr/src/app
   COPY package*.json ./
   RUN npm ci
   COPY . .
   USER node

   # Build stage
   FROM node:20-alpine AS build
   WORKDIR /usr/src/app
   COPY package*.json ./
   COPY --from=development /usr/src/app/node_modules ./node_modules
   COPY . .
   RUN npm run build
   ENV NODE_ENV production
   RUN npm ci --only=production && npm cache clean --force
   USER node

   # Production stage
   FROM node:20-alpine AS production
   WORKDIR /usr/src/app
   COPY --from=build /usr/src/app/node_modules ./node_modules
   COPY --from=build /usr/src/app/dist ./dist
   CMD ["node", "dist/main.js"]
Enter fullscreen mode

Exit fullscreen mode

This setup uses three stages:

  • development: For local development with all dependencies.
  • build: Builds the application for production.
  • production: The final stage that runs the production build.



Step 4: Rebuilding and Running the Optimized Image

After updating your Dockerfile, rebuild the image:

docker build -t nest-app .
Enter fullscreen mode

Exit fullscreen mode

Then, run the new optimized container:

docker run -p 3000:3000 nest-app
Enter fullscreen mode

Exit fullscreen mode

Check the size of the new image with:

docker images
Enter fullscreen mode

Exit fullscreen mode

You should see a significant reduction in the image size, making it more efficient for production use.



Troubleshooting Common Issues

  • Error: Cannot find module ‘webpack’: Ensure you’re using the correct Node.js version in your base image. For example, use FROM node:20-alpine instead of FROM node:14-alpine.
  • Error: nest command not found: This usually happens if the Nest CLI is not installed. In a multistage build, make sure you copy over the node_modules directory from the development stage where the CLI is installed.



Using Different Package Managers

If you’re using pnpm instead of npm, your Dockerfile would look slightly different. Here’s an example:

# Development stage
FROM node:20 AS development
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY pnpm-lock.yaml ./
RUN pnpm fetch --prod
COPY . .
RUN pnpm install
USER node

# Build stage
FROM node:20 AS build
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY pnpm-lock.yaml ./
COPY --from=development /usr/src/app/node_modules ./node_modules
COPY . .
RUN pnpm build
ENV NODE_ENV production
RUN pnpm install --prod
USER node

# Production stage
FROM node:20-alpine AS production
WORKDIR /usr/src/app
COPY --from=build /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/dist ./dist
CMD ["node", "dist/main.js"]
Enter fullscreen mode

Exit fullscreen mode



Using Fastify with NestJS

If you’re using Fastify instead of Express, you’ll need to modify your main.ts to listen on 0.0.0.0:

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(process.env.PORT || 3000, '0.0.0.0');
}
bootstrap();
Enter fullscreen mode

Exit fullscreen mode

That’s it! You now have a dockerized NestJS application that’s optimized for production. If you want to deploy your NestJS app, check out sliplane.io

Cheers,
Jonas



Source link
lol

By stp2y

Leave a Reply

Your email address will not be published. Required fields are marked *

No widgets found. Go to Widget page and add the widget in Offcanvas Sidebar Widget Area.