Dockerizing NestJs application for production

Dockerizing NestJs application for production

·

4 min read

Prerequisites

Containerized Nest Js Application

Creating Dockerfile with multi-stage build

create a file named Dockerfile in the root directory of the nestjs application

Replace 9009 with your application port

FROM node:12 As development
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:12-alpine As production
RUN apk update && apk upgrade && \
  apk add --no-cache bash git openssh
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . .
COPY --from=development /usr/src/app/dist ./dist
EXPOSE 9009
CMD ["node", "dist/main"]

Creating .dockerignore

From the official docs of docker for .dockerignore:

Before the docker CLI sends the context to the docker daemon, it looks for a file named .dockerignore in the root directory of the context. If this file exists, the CLI modifies the context to exclude files and directories that match patterns in it. This helps to avoid unnecessarily sending large or sensitive files and directories to the daemon and potentially adding them to images using ADD or COPY.

node_modules
npm-debug.log
dist

Build Docker Image

When building an image, we use the following command:

docker build -t username/image_name:tag_name .

in the below command replace api with your application name

docker build -t sreeteja06/api:v0.1 .

Running the image

replace api with your application name

replace 9009:9009 with your application port

docker run -p 9009:9009 api

Run detached

docker run -d -p 9009:9009 api

docker-compose

docker-compose helps developers with their local development. Since our application is containerized and works the same on every machine, why should our database be dependent on the developer’s machine?

We are going to create a docker-compose config that will initiate and wire up three services for us.

The mariadb service will, as their names imply, run containerized mariadb.

In the application root directory, create a file called docker-compose.yml and fill it with the following content:

replace api with your application name and 9009:9009 with your port

version: '3.7'

services:
  db:
    image: mariadb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: user
    ports:
      - 3306:3306
    volumes:
      - mariadb-data:/data

  api:
    image: api
    restart: always
    ports:
      - 9009:9009

volumes:
  mariadb-data:

Running the application in development

To run the application, we now have to use the following command:

docker-compose up

Run Detached

docker-compose up -d

And Docker will take care of everything for us.

Stop docker-compose by running

docker-compose down

Remove volumes by running

docker-compose down -v