notiz-dev / notiz

Frontend for notiz.dev. Built with Angular and Scully 👋
https://notiz.dev
67 stars 9 forks source link

Dockerizing a NestJS app with Prisma and PostgreSQL #145

Closed utterances-bot closed 3 years ago

utterances-bot commented 3 years ago

Dockerizing a NestJS app with Prisma and PostgreSQL

How to dockerize a NestJS application with Prisma and PostgreSQL.

https://notiz.dev/blog/dockerizing-nestjs-with-prisma-and-postgresql

joshuacrowley commented 3 years ago

Thanks for the detailed article, was really helpful and got me unstuck!

MatthieuVeillon commented 3 years ago

Hi Marc - some great content here, thanks for the detailed article.

I was wondering about the switch from postgres to localhost as the database url host. Several questions linked to that :

marcjulian commented 3 years ago

@MatthieuVeillon thank your!

Let me try to clarify the differences of localhost and container_name (postgress).

When you start a docker container on your development machine it will be accessible via localhost:PORT. For a PostgreSQL DB it would be localhost:5432. That means if you like to connect to the database locally via Nest App (npm run start:dev), Prisma Studio or perform Migration from your computer than you use localhost:PORT.

When you start know a DB and Nest Docker container you want Nest and Docker to communicate together. If you use localhost:PORT in the connection URL and the nest app is trying to connect, it won't find the db. Because localhost would be the nest container itself. Hence you need to reference the container by name or service. In the example the service and the container name are the same, so in that case for your Nest container you would need to replace localhost:PORT with container_name:PORT (-> from the blog post postgres:PORT).

Does that answer your question?

MatthieuVeillon commented 3 years ago

That does make perfect sense yes. Communicating between containers themselves vs from the local env.

I realized since then that I had modified my host file to map the postgres host to my localhost. 🤦‍♂️

Thanks for your clarification !

tannaurus commented 3 years ago

Forgive me, I'm still fairly new to Docker. Why are we:

COPY prisma ./prisma/ then also COPY . .

Isn't that redundant?

marcjulian commented 3 years ago

Only package*.json and prisma directory is copied in this step to take advantage of the cached Docker layers.

Each command (COPY, RUN) in your Dockerfile creates a new layer, Docker tries to use existing cached layers. If you directly copy all source files (COPY . .) it will still work, however everytime you make a change in any source file docker invalides the cached layer and has to execute RUN npm i again. Those losing performance during development as npm i may take sometime depending on the amount of dependencies.

When you first copy package*.json and prisma directory and install the dependencies, and then only change your source code - e.g. adding new API endpoint - Docker can reuse the existing chached layers and your Docker Image is create faster.

Read more about cached layers in Building Efficient Dockerfiles - Node.js.

tannaurus commented 3 years ago

Brilliant @marcjulian. Thanks for that reply and your great article 👍

victororlyk commented 3 years ago

I have very strange bug , when trying to make a call to db in docker, it throws next error, while in local dev there is no such error

nest-api | [Nest] 29 - 06/12/2021, 8:43:24 AM [ExceptionsHandler] The table `borda.User` does not exist in the current database. +110958ms

nest-api | Error: The table `borda.User` does not exist in the current database.
tannaurus commented 3 years ago

@victororlyk sounds like you need to run a migration on your docker DB

victororlyk commented 3 years ago

@tannaurus you are right, I

FROM node:14.17-alpine3.13 as development

WORKDIR /app

COPY package.json package.json
COPY yarn.lock yarn.lock
COPY prisma ./prisma/

RUN yarn install

RUN npx prisma generate
# RUN npx prisma migrate dev --name base-setup  init
COPY .. .
RUN yarn run build

FROM node:14.17-alpine3.13 as production

COPY --from=development /app/node_modules ./node_modules
COPY --from=development /app/package.json ./
COPY --from=development /app/yarn.lock ./
COPY --from=development /app/dist ./dist

CMD ["yarn", "run", "start:prod"]

#docker build -t borda-backend .

that this setup will do the trick, but actually i needed to switch DB_HOST to localhost and run migrations agains it, and then my db worked fine. Thanks for the advice

patryk0493 commented 3 years ago

Great guide!!! What about running a migration on production when I running my app on the Google Cloud Platform?

antoinfive commented 3 years ago

@patryk0493 also curious about this. my guess is that you would run:

RUN npx prisma migrate deploy

but I am curious how others go about this