skip to Main Content

I have created a NextJS application, to connect to the database I use Prisma. When I start the application on my computer everything works. Unfortunately, I get error messages when I try to run the application in a Docker container. The container can be created and started. The start page of the application can also be shown (there are no database queries there yet). However, when I click on the first page where there is a database query I get error code 500 – Initial Server Error and the following error message in the console:

PrismaClientInitializationError: Unknown PRISMA_QUERY_ENGINE_LIBRARY undefined. Possible binaryTargets: darwin, darwin-arm64, debian-openssl-1.0.x, debian-openssl-1.1.x, rhel-openssl-1.0.x, rhel-openssl-1.1.x, linux-arm64-openssl-1.1.x, linux-arm64-openssl-1.0.x, linux-arm-openssl-1.1.x, linux-arm-openssl-1.0.x, linux-musl, linux-nixos, windows, freebsd11, freebsd12, openbsd, netbsd, arm, native or a path to the query engine library.
You may have to run prisma generate for your changes to take effect.
    at cb (/usr/src/node_modules/@prisma/client/runtime/index.js:38689:17)
    at async getServerSideProps (/usr/src/.next/server/pages/admin/admin.js:199:20)
    at async Object.renderToHTML (/usr/src/node_modules/next/dist/server/render.js:428:24)
    at async doRender (/usr/src/node_modules/next/dist/server/next-server.js:1144:38)
    at async /usr/src/node_modules/next/dist/server/next-server.js:1236:28
    at async /usr/src/node_modules/next/dist/server/response-cache.js:64:36 {
  clientVersion: '3.6.0',
  errorCode: undefined
}

My Dockerfile:

# Dockerfile

# base image
FROM node:16-alpine3.12

# create & set working directory
RUN mkdir -p /usr/src
WORKDIR /usr/src

# copy source files
COPY . /usr/src

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

# install dependencies
RUN npm install

COPY . .

# start app
RUN npm run build
EXPOSE 3000
CMD npm run start

My docker-compose.yaml:

version: "3"

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: web
    restart: always
    volumes:
      - ./:/usr/src/app
    ports:
      - "3000:3000"
    env_file:
      - .env

My package.json:

{
    "name": "supermarket",
    "version": "0.1.0",
    "private": true,
    "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint"
    },
    "prisma": {
        "schema": "prisma/schema.prisma"
      },
    "dependencies": {
        "@prisma/client": "^3.6.0",
        "axios": "^0.22.0",
        "cookie": "^0.4.1",
        "next": "latest",
        "nodemailer": "^6.6.5",
        "react": "17.0.2",
        "react-cookie": "^4.1.1",
        "react-dom": "17.0.2"
    },
    "devDependencies": {
        "eslint": "7.32.0",
        "eslint-config-next": "11.1.2",
        "prisma": "^3.6.0"
    }
}

4

Answers


  1. Chosen as BEST ANSWER

    I've found the error. I think it's a problem with the M1 Chip. I changed node:16-alpine3.12 to node:lts and added some commands to the Dockerfile which looks like this now:

    # base image
    FROM node:lts
    
    # create & set working directory
    RUN mkdir -p /usr/src
    WORKDIR /usr/src
    
    # copy source files
    COPY . /usr/src
    
    COPY package*.json ./
    COPY prisma ./prisma/
    
    RUN apt-get -qy update && apt-get -qy install openssl
    
    # install dependencies
    RUN npm install
    
    RUN npm install @prisma/client
    
    COPY . .
    RUN npx prisma generate --schema ./prisma/schema.prisma
    # start app
    RUN npm run build
    EXPOSE 3000
    CMD npm run start
    

    I hope this can also help other people 😊


  2. I have been having a similar issue, which I have just solved.

    I think what you need to do is change the last block in your docker file to this

    # start app
    RUN npm run build
    RUN npx prism generate
    EXPOSE 3000
    CMD npm run start
    

    I think that will solve your issue.

    Login or Signup to reply.

  3. I had a luck this way:

    FROM node:17-slim as dependencies
    
    
    # set working directory
    WORKDIR /usr/src/app
    
    # Copy package and lockfile
    COPY package.json ./
    COPY yarn.lock ./
    COPY prisma ./prisma/
    RUN apt-get -qy update && apt-get -qy install openssl
    
    # install dependencies
    RUN yarn --frozen-lockfile
    
    COPY . .
    
    # ---- Build ----
    FROM dependencies as build
    # install all dependencies
    
    # build project
    RUN yarn build
    
    # ---- Release ----
    FROM dependencies as release
    # copy build
    COPY --from=build /usr/src/app/.next ./.next
    COPY --from=build /usr/src/app/public ./public
    
    # dont run as root
    USER node
    
    # expose and set port number to 3000
    EXPOSE 3000
    ENV PORT 3000
    
    # enable run as production
    ENV NODE_ENV=production
    
    # start app
    CMD ["yarn", "start"]
    
    Login or Signup to reply.
  4. I’ve found this solution with some workarounds:
    https://gist.github.com/malteneuss/a7fafae22ea81e778654f72c16fe58d3
    In short:

    # Dockerfile
    
    ...
    FROM node:16-alpine AS builder
    WORKDIR /app
    COPY --from=deps /app/node_modules ./node_modules
    COPY . .
    RUN npx prisma generate                   # <---important to support Prisma query engine in Alpine Linux in final image
    RUN npm run build
    
    # Production image, copy all the files and run next
    FROM node:16-alpine AS runner
    WORKDIR /app
    ...
    COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
    COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
    COPY --chown=nextjs:nodejs prisma ./prisma/                # <---important to support Prisma DB migrations in bootstrap.sh
    COPY --chown=nextjs:nodejs bootstrap.sh ./
    ...
    CMD ["./bootstrap.sh"]
    

    This Dockerfile is based on the official Nextjs with Docker example project and adapted to include Prisma. To run migrations on app start we can add a bash script that does so:

    # bootstrap.sh
    
    #!/bin/sh
    # Run migrations
    DATABASE_URL="postgres://postgres:postgres@db:5432/appdb?sslmode=disable" npx prisma migrate deploy
    # start app
    DATABASE_URL="postgres://postgres:postgres@db:5432/workler?sslmode=disable" node server.js
    

    Unfortunately, we need to explicitly set the DATABASE_URL here, otherwise migrations don’t work, because Prisma can’t find the environment variable (e.g. from a docker-compose file).
    And last but not least, because Alpine Linux base image uses a Musl C-library, the Prisma client has to be compiled in the builder image against that. So, to get the correct version, we need to add this info to Prisma’s schema.prisma file:

    # schema.prisma
    
    generator client {
      provider = "prisma-client-js"
      binaryTargets = ["native", "linux-musl"] # <---- important to support Prisma Query engine in Alpine linux, otherwise "PrismaClientInitializationError2 [PrismaClientInitializationError]: Query engine binary for current platform "linux-musl" could not be found."
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search