I’m working on a Nextjs application using Prisma as ORM, where the Docker container is built via GitHub Actions and deployed to Kubernetes across environments for multiple user organizations (let’s call them "clients").
My question is : How would you apply Prisma migrations to the client databases during upgrades?
Prisma's documentation suggests applying migrations through the CI/CD pipeline. However, in our case, this is not an option because:
With other ORMs like Python/Alembic, I’ve handled this by integrating migrations into Kubernetes deployment args to overwrite the Docker entrypoint (which is fine as long as several containers don't try to start concurrently).
apiVersion: apps/v1
kind: Deployment
spec:
containers:
- name: container-name
args:
- bash
- -c
- alembic upgrade heads && uvicorn app.main:app ...
However, in the case of Prisma, with a multi-stage build that only embeds the Prisma client (discarding build-time dependencies), this approach isn’t viable. Embedding the entire Prisma library would result in a bloated container image. Should migrations be deployed separately via a dedicated Job? Or do you recommend other approaches?
This is how I did it in one of my projects:
Dockerfile
, ensure the prisma
folder is COPY
-ed over into the final stage:# Assuming /builder/ is WORKDIR of the builder stage
COPY --from=builder /builder/prisma ./prisma
package.json
file to call prisma migration command inside the start
command: "scripts": {
"dev": "next dev",
"build": "next build",
"start": "npx prisma migrate deploy && next start",
"lint": "next lint"
},
CMD
command in Dockerfile
call npm start
:CMD ["npm", "start"]
If you prefer to use an init container to perform the migration, just modify step 2 to bind something like npm migrate
script to the npx prisma migrate deploy
command and override the args of that init container to call npm migrate
instead of npm start
:
"scripts": {
"dev": "next dev",
"build": "next build",
"migrate": "npx prisma migrate deploy",
"start": "next start",
"lint": "next lint"
},