For my project, it seems to work fine by using the following structure. Only 2 folder needed (dist, node_modules) and 2 files (package.json and package-lock.json)
######### First Stage ############# FROM node:20-alpine AS development WORKDIR /app COPY --chown=node:node ./app ./ RUN npm ci \ && npx prisma generate \ && npm run build \ && npm prune --omit=dev ######### Second Stage ############# FROM node:20-alpine AS production WORKDIR /var/www/app # Create the necessary directories with correct permissions COPY --chown=node:node --from=development /app/node_modules ./node_modules COPY --chown=node:node --from=development /app/dist ./dist COPY --chown=node:node --from=development /app/package*.json ./ # Switch to the non-root user USER node EXPOSE 3000 CMD ["node", "dist/src/main"]
where my project folder has the following structure:
/myproject
Dockerfile
/app
package.json
...
... (other nestjs files)
...
/src
/prisma
package.json definition:
....
"prisma": {
"schema": "./src/prisma/schema.prisma"
}
....
Hope it helps.
TLDR: Does anyone have a tutorial on how to set up Node (Next.js) + Prisma + Postgres with Docker Compose in 2023?
Hey everyone! I'm a junior Python developer who has been getting into web dev lately, and I've been struggling on a problem for days without a solution. I was hoping someone here might be able to help!
Specifically, I'm having trouble dockerizing a Next.js application that uses Prisma + Postgres. I'm hoping someone might be able to provide some guidance on how to do this in 2023. All of the tutorials I've seen have had different methods of doing this, some using deprecated compose features, some setting up Prisma as a separate service, etc. Any guidance is appreciated!
Just remove the following line from the schema.prisma file:
output = "../generated/prisma"
and execute:
npx prisma generate
I know that this has been marked as solved, but I just wanted to share my setup for anyone interested.
Dockerfile
# Build image
FROM node:16.13-alpine as builder
WORKDIR /app
# Not sure if you will need this
# RUN apk add --update openssl
COPY package*.json ./
RUN npm ci --quiet
COPY ./prisma prisma
COPY ./src src
RUN npm run build
# Production image
FROM node:16.13-alpine
WORKDIR /app
ENV NODE_ENV production
COPY package*.json ./
RUN npm ci --only=production --quiet
COPY --chown=node:node --from=builder /app/prisma /app/prisma
COPY --chown=node:node --from=builder /app/src /app/src
USER node
EXPOSE 8080
CMD ["node", "src/index.js"]
package.json
{
"name": "example",
"description": "",
"version": "0.1.0",
"scripts": {
"generate": "npx prisma generate",
"deploy": "npx prisma migrate deploy",
"dev": "npm run generate && nodemon --watch \"src/**\" --ext \"js,json\" --exec \"node src/index.js\"",
"build": "npm run generate",
"start": "npm run build && node build/index.js"
},
"prisma": {
"schema": "prisma/schema.prisma"
},
"dependencies": {
"@prisma/client": "^3.6.0"
},
"devDependencies": {
"@tsconfig/node16": "^1.0.2",
"@types/node": "^16.11.12",
"nodemon": "^2.0.15",
"prisma": "^3.6.0"
}
}
I run this in Kubernetes. To make things smooth with database and migrations I run an initContainer that runs the prisma migrate deploy.
apiVersion: apps/v1
kind: Deployment
metadata:
name: EXAMPLE
spec:
replicas: 1
selector:
matchLabels:
app: EXAMPLE
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: EXAMPLE
spec:
containers:
image: DOCKER_IMAGE
imagePullPolicy: IfNotPresent
name: SERVICE_NAME
ports:
- containerPort: 8080
name: http
protocol: TCP
initContainers:
- command:
- npm
- run
- deploy
image: DOCKER_IMAGE
imagePullPolicy: IfNotPresent
name: database-migrate-deploy
(This is a live service I just copied and stripped away anything non essential)
I hope this could be of use to someone