VibeJolt

How to update the prisma in a production docker instance?

I have a node.js application that I run on EC2, and I have that application running on production. After a while, I update the database(schema) by creating another table, how can I also run the migration on the docker container after I update the latest docker image and create a new container from that image without deleting the data but just applying the migration?

That is the dockerfile:

# Use an official Node.js runtime as the base image FROM node:16.15.1-alpine as builder # Set the working directory in the container WORKDIR /app # Copy the package.json and package-lock.json files to the container COPY package*.json ./ # Install project dependencies RUN npm install # Copy the rest of the application code to the container COPY . . # Generate the Prisma client RUN npx prisma generate # Expose the port on which your Node.js application will listen EXPOSE 4500 # Set the command to run your Node.js application CMD ["npm", "start"] 
3

1 Answer

Your Dockerfile currently generates the Prisma client, but it does not run the Prisma migrations, which are necessary to update the database schema.

Running such a step at build time seems not a good practice at it would look like:

docker build --build-arg DATABASE_URL=postgresql://user:password@localhost:5432/mydb \ -t my-app . 

With your Dockerfile including ARG DATABASE_URL. And... that means your credentials are embedded in the Docker image layer, visible through any docker inspect.

Another approach would be to make the migration at runtime, when starting the container.

Assuming:

  • you have a backup in place, and that
  • your database is already accessible and that
  • the required environment variables for Prisma to connect to your database are provided at build time.

Then you can use a Docker entrypoint script entrypoint.sh that runs when your Docker container is started. That script can first run the migrations, then start your application.
I am using migrate status, but be aware this command is not supported on MongoDB. Use db push instead.

#!/bin/sh MIGRATION_STATUS=$(npx prisma migrate status) if echo "$MIGRATION_STATUS" | grep -q "Database schema is up to date"; then echo "No migrations needed." else echo "Running migrations..." npx prisma migrate deploy fi npm start 

Then in your Dockerfile:

# Use an official Node.js runtime as the base image FROM node:16.15.1-alpine as builder # Set the working directory in the container WORKDIR /app # Copy the package.json and package-lock.json files to the container COPY package*.json ./ # Install project dependencies RUN npm install # Copy the rest of the application code to the container COPY . . # Generate the Prisma client RUN npx prisma generate # Copy the entrypoint script into the container COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh # Expose the port on which your Node.js application will listen EXPOSE 4500 # Set the entrypoint script as the command to run ENTRYPOINT ["/entrypoint.sh"] 

You are passing the DATABASE_URL when running the container, and the migration step is run at that time, just before your application starts:

docker run -e DATABASE_URL=postgresql://user:password@localhost:5432/mydb -d my-app 

And on the next schema update, you do not have to build a new image.

But the npx maybe will not be recognized as a command

That is a valid point. If the Node.js environment is not properly set up or if the PATH environment variable is not correctly configured, npx may not be recognized as a command inside your container.

In your Dockerfile, you are using node:16.15.1-alpine as your base image, which already includes Node.js and npm.

By default, Node.js and npm binaries should be added to your PATH in the node:16.15.1-alpine Docker image.
If you encounter the "npx: command not found" error, try checking the PATH environment variable inside your container. You could do this by adding the following command to your Dockerfile:

RUN echo $PATH 

That will print out the PATH variable during the Docker build process, allowing you to verify that the Node.js binary directory is included.

3

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobm9uaW2Cc4WOoaawZaSkera8w5qrnmWknbJuvNGiqqaZXZ67bq2MqamonKWYwaq7zWabqJubmr9utc2sq5qmk5o%3D

Abbie Anker

Update: 2024-05-21