dockerdocker-composeprismajose

Docker Compose suddenly having trouble with Prisma and Jose


I have a dockerized Next.js project using Prisma. I was working on it as usual, didn't change anything about the Docker setup, the file locations or packages, I just wanted to rebuild the container to pull new environment variables.

Then I receive this error:

90.79 > hey-shop@0.1.0 postinstall
90.79 > prisma generate
90.79 
91.03 Error: Could not find Prisma Schema that is required for this command.
91.03 You can either provide it with `--schema` argument, set it as `prisma.schema` in your package.json or put it into the default location.
91.03 Checked following paths:
91.03 
91.03 schema.prisma: file not found
91.03 prisma/schema.prisma: file not found
91.03 prisma/schema: directory not found
91.03 
91.03 See also https://pris.ly/d/prisma-schema-location
91.03 npm notice
91.03 npm notice New minor version of npm available! 10.7.0 -> 10.8.1
91.03 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.8.1
91.03 npm notice To update run: npm install -g npm@10.8.1
91.03 npm notice
91.03 npm error code 1
91.03 npm error path /app
91.03 npm error command failed
91.03 npm error command sh -c prisma generate
91.04 
91.04 npm error A complete log of this run can be found in: /root/.npm/_logs/2024-06-28T08_02_21_293Z-debug-0.log
------
failed to solve: process "/bin/sh -c npm install" did not complete successfully: exit code: 1

This is my package.json scripts section:

"scripts": {
    "dev": "next dev",
    "build": "next-swagger-doc-cli next-swagger-doc.json && next build",
    "start": "next start",
    "lint": "next lint",
    "resetdb": "cross-env NODE_ENV=test npx prisma db push --force-reset && npx prisma db seed",
    "postinstall": "prisma generate",
    "generate-docs": "next-swagger-doc-cli next-swagger-doc.json",
    "test": "cross-env NODE_ENV=test jest",
    "test:watch": "cross-env NODE_ENV=test jest --watch"
  },
  "prisma": {
    "seed": "tsx prisma/seed.ts"
  },

Until then I had no issues running these scripts. It also makes no difference to the error when I specify --schema='/prisma/schema.prisma'. My file structure is the following:

When I remove the postinstall script, this part seems to work. I don't need the postinstall anymore anyways - it was for generating an erd, but the corresponding package has vulnerabilities.

However, now my auth middleware creates trouble, especially Jose, which I use for JWTs.

web-1       |  ○ Compiling / ...
web-1       |  ⨯ ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | Attempted import error: 'normalizePrivateKey' is not exported from '../runtime/normalize_key.js' (imported as 'normalize').
web-1       | 
web-1       | Import trace for requested module:
web-1       | ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | ./node_modules/jose/dist/node/esm/jwe/flattened/decrypt.js
web-1       | ./node_modules/jose/dist/node/esm/index.js
web-1       | ./app/lib/auth.ts
web-1       | ./app/lib/utils/api-authorization.ts
web-1       | ./app/(general)/layout.tsx
web-1       |  ⨯ ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | Attempted import error: 'normalizePrivateKey' is not exported from '../runtime/normalize_key.js' (imported as 'normalize').
web-1       | 
web-1       | Import trace for requested module:
web-1       | ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | ./node_modules/jose/dist/node/esm/jwe/flattened/decrypt.js
web-1       | ./node_modules/jose/dist/node/esm/index.js
web-1       | ./app/lib/auth.ts
web-1       | ./app/ui/search/pagination.tsx
web-1       | ./app/(general)/page.tsx
web-1       |  ⨯ ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | Attempted import error: 'normalizePrivateKey' is not exported from '../runtime/normalize_key.js' (imported as 'normalize').
web-1       | 
web-1       | Import trace for requested module:
web-1       | ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | ./node_modules/jose/dist/node/esm/jwe/flattened/decrypt.js
web-1       | ./node_modules/jose/dist/node/esm/index.js
web-1       | ./app/lib/auth.ts
web-1       | ./app/ui/search/pagination.tsx
web-1       | ./app/(general)/page.tsx
web-1       |  ⨯ ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | Attempted import error: 'normalizePrivateKey' is not exported from '../runtime/normalize_key.js' (imported as 'normalize').
web-1       | 
web-1       | Import trace for requested module:
web-1       | ./node_modules/jose/dist/node/esm/lib/decrypt_key_management.js
web-1       | ./node_modules/jose/dist/node/esm/jwe/flattened/decrypt.js
web-1       | ./node_modules/jose/dist/node/esm/index.js
web-1       | ./app/lib/auth.ts
web-1       | ./app/ui/search/pagination.tsx
web-1       | ./app/(general)/page.tsx

And this is the part where I get stuck. I don't understand why suddenly this error appears. I am on a recent version of jose, have checked their forums and find nothing.

Here is my docker-compose:

services:
  postgres:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    ports:
      - 5432:5432
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "sh -c 'pg_isready -U postgres -d postgres'"]
      interval: 10s
      timeout: 3s
      retries: 3

  web:
    build:
      context: .
      args:
        - VERCEL_TOKEN=${VERCEL_TOKEN}
    volumes:
      - ./app:/app/app
      - ./prisma:/app/prisma
      - ./public:/app/public
      - ./swagger:/app/swagger
    ports:
      - 3000:3000
      - 5555:5555
    depends_on:
      - postgres

volumes:
  postgres-data:

Here is my Dockerfile:

FROM node:20

WORKDIR /app

COPY package.json ./

RUN npm install

RUN npm install --global vercel@latest

COPY . .

ARG VERCEL_TOKEN
RUN vercel env pull .env --environment=Development --token=$VERCEL_TOKEN

RUN npx prisma generate --schema ./prisma/schema.prisma

ENV POSTGRES_DATABASE=postgres
ENV POSTGRES_USER=postgres
ENV POSTGRES_PASSWORD=postgres
ENV POSTGRES_HOST=postgres
ENV POSTGRES_URL=postgres://postgres:postgres@postgres:5432/postgres?connect_timeout=300&schema=public
ENV POSTGRES_PRISMA_URL=postgres://postgres:postgres@postgres:5432/postgres?connect_timeout=300&schema=public
ENV POSTGRES_URL_NON_POOLING=postgres://postgres:postgres@postgres:5432/postgres?connect_timeout=300&schema=public
ENV POSTGRES_PORT=5432

EXPOSE 3000

CMD ["npm", "run", "dev"]

I have found nothing online for this error, nobody ever seemed to have this issue. I purged all docker containers and ran docker system prune with a clean rebuild but no luck. I don't know what else to try here.

Edit: my dockerignore:

**/node_modules
.next
.swc
.env

Solution

  • Ok so after fiddling around, I have somehow resolved the issue, but I am not quite sure why.

    I removed the postinstall script in order to be able to spin up the container. Then I get the jose error as stated in my question but at least the container is running. I entered the container with docker exec -it hey-shop-web-1 bash and there I deleted the node_modules folder. I then ran npm install inside the container, stopped the containers and ran docker-compose up without the build flag. And now everything was working, however I could not run docker-compose up --build without getting this jose error again. This part I was able to solve by changing my Dockerfile from COPY package.json ./ to COPY package*.json ./. And now it works perfectly every time.

    In the end the only thing I did was to change my Dockerfile to:

    FROM node:20
    
    WORKDIR /app
    
    COPY package*.json ./
    
    RUN npm install
    
    RUN npm install --global vercel@latest
    
    COPY . .
    
    ARG VERCEL_TOKEN
    RUN vercel env pull .env --environment=Development --token=$VERCEL_TOKEN
    
    ENV POSTGRES_DATABASE=postgres
    ENV POSTGRES_USER=postgres
    ENV POSTGRES_PASSWORD=postgres
    ENV POSTGRES_HOST=postgres
    ENV POSTGRES_URL=postgres://postgres:postgres@postgres:5432/postgres?connect_timeout=300&schema=public
    ENV POSTGRES_PRISMA_URL=postgres://postgres:postgres@postgres:5432/postgres?connect_timeout=300&schema=public
    ENV POSTGRES_URL_NON_POOLING=postgres://postgres:postgres@postgres:5432/postgres?connect_timeout=300&schema=public
    ENV POSTGRES_PORT=5432
    
    EXPOSE 3000
    
    CMD ["npm", "run", "dev"]
    

    I thought that somehow my MacOS node_modules got into the Linux container and that caused the issue, but I don't know how that can be when I specifically added **/node_modules to the .dockerignore and I am installing them in my Dockerfile anyways. But I also noticed, that the installation of node modules was way quicker now. When I had the errors coming up, the npm install would take almost 500 seconds whereas after the fix it is now at roughly 30 seconds. I read somewhere that npm install would take so long in a docker container when it synced with the main OS. I think this might be what happened and that the install now is so quick is evidence that now there is no syncing going on. But I don't know how that would have happened in the first place.

    Secondly, the postinstall error vanished as well. I was able to remove the prisma generate process from the Dockerfile and add the postinstall script back to the package.json. (Luckily, as I actually needed the postinstall for hosting on vercel)

    If someone has any explanation or an idea of what is going on there, I appreciate your input.