DEV Community

Cover image for Dockerizing a NestJS app and persisting data
Chafroud Tarek
Chafroud Tarek

Posted on • Updated on

Dockerizing a NestJS app and persisting data

It has been a while since our last post, and we have successfully achieved our goal of reaching 20k this year. I am extremely glad, and this achievement motivates me to do a lot more. Hopefully, this year, Inshallah, we will reach 50k. Anyway, let's begin. Our topic revolves around Dockerizing a NestJS app and persisting data.

In this scenario, I'll be utilizing PostgreSQL and Prisma. I'll assume you're already familiar with creating a NestJS application and integrating Prisma. If not, please leave a comment below, and I'll create a dedicated post on the process.

1- Setup your nestjs app

2- Add dockerFile:
Create it as a regular file within your project, not within the 'src' directory but at the same level as 'package.json'. Simply name it Dockerfile
i will explain it line by line :
▶ builder stage:
❶ : FROM node:latest AS builder :
- This line sets the starting point for building our Docker image by using the most recent version of Node.js from Docker Hub.

 ❷ : WORKDIR /app :
        -  Sets the working directory inside the Docker container to /app

❸ : COPY package*.json ./
    COPY prisma ./prisma/ : 
       - COPY package*.json ./ and COPY prisma ./prisma/: Copies the package.json and package-lock.json files as well as the prisma directory from the host machine to the /app directory in the container
Enter fullscreen mode Exit fullscreen mode

❹ : RUN npm install --force :
- Executes the npm install command to install the project dependencies defined in package.json.

❺ : COPY . . :
- Copies all files from the current directory of the host machine to the /app directory in the container

❻ : RUN npm run build :
- Executes the command to build the project

▶ Final stage : This is the final image that will be created. It's based on the Node.js image without any specific name/alias.
Enter fullscreen mode Exit fullscreen mode

copies only the essential artifacts needed to run the application from the "builder" stage (node_modules, package*.json, dist directory). This selective copying helps keep the final image small and efficient.

❶ : FROM node:latest

❷ : WORKDIR /app

❸ :
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
- Copies specific directories from the 'builder' stage to the respective directories in the new stage

     ❹ : EXPOSE 3000 : 
   -  Informs Docker that the container listens on port 3000 at runtime

    ❺ : CMD [ "npm", "run", "start:prod" ]:
  - Specifies the default command to be executed when the container starts
Enter fullscreen mode Exit fullscreen mode

the final result :

FROM node:latest AS builder

WORKDIR /app

COPY package*.json ./
COPY prisma ./prisma/

RUN npm install --force

COPY . .

RUN npm run build

FROM node:latest

WORKDIR /app

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist

EXPOSE 3000
CMD [ "npm", "run", "start:prod" ]
Enter fullscreen mode Exit fullscreen mode

The next crucial step is to generate a 'docker-compose.yml' file at the same level as the 'Dockerfile'.

❶ : version: '1.1' # Specifies the version of the Compose file format being used.
❷ : services: will contain our services :

Image description


Image description


Image description

the final result will be like this :

version: '3.8'
services:
  prisma-migrate:
    container_name: prisma-migrate
    build:
      context: prisma
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: ${DATABASE_URL}
    depends_on:
      - postgres

  postgres:
    image: postgres:13
    container_name: postgres
    restart: always
    ports:
      - '5432:5432'
    env_file:
      - .env
    volumes:
      - postgres:/var/lib/postgresql/data

  pgadmin:
    image: dpage/pgadmin4
    restart: always
    container_name: nest-pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=admin@admin.com
      - PGADMIN_DEFAULT_PASSWORD=pgadmin4
    ports:
      - '5050:80'
    depends_on:
      - postgres

volumes:
  postgres:
    name: nest-db

Enter fullscreen mode Exit fullscreen mode

and now just run : *docker compose up -d *

Hopefully, this brings value and aids you,Feel free to leave a comment if this was helpful or if you have any questions. I'm here and ready to provide further assistance.for more tips you can follow me here linkedin.

Top comments (0)