skip to Main Content

I have a next 14 app that uses Prisma as the ORM and am using a Sqlite db locally for dev testing. I don’t want to use an image for MySQL or Mongo or Postgres etc…

In trying to use docker compose I am having issues running the container and having the project show up on port 3000.

The specific error:

Server Error
Error: @prisma/client did not initialize yet. Please run "prisma generate" and try to import it again.
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
src/db/index.ts (3:22) @ eval

  1 | import { PrismaClient } from "@prisma/client";
  2 |
> 3 | export const prisma = new PrismaClient();

Dockerfile

# set the base image to create the image for react app
FROM node:20-alpine

# create a user with permissions to run the app
# -S -> create a system user
# -G -> add the user to a group
# This is done to avoid running the app as root
# If the app is run as root, any vulnerability in the app can be exploited to gain access to the host system
# It's a good practice to run the app as a non-root user
RUN addgroup app && adduser -S -G app app

# set the user to run the app
USER app

# set the working directory to /app
WORKDIR /app

# copy package.json and package-lock.json to the working directory
# This is done before copying the rest of the files to take advantage of Docker’s cache
# If the package.json and package-lock.json files haven’t changed, Docker will use the cached dependencies
COPY package*.json ./
COPY ./prisma prisma

# sometimes the ownership of the files in the working directory is changed to root
# and thus the app can't access the files and throws an error -> EACCES: permission denied
# to avoid this, change the ownership of the files to the root user
USER root

# change the ownership of the /app directory to the app user
# chown -R <user>:<group> <directory>
# chown command changes the user and/or group ownership of for given file.
RUN chown -R app:app .

# change the user back to the app user
USER app

# init prisma
RUN npx prisma generate --schema=./prisma/schema.prisma

# install dependencies
RUN npm install

# copy the rest of the files to the working directory
COPY . .

# expose port 3000 to tell Docker that the container listens on the specified network ports at runtime
EXPOSE 3000

# command to run the app
CMD npm run dev

Compose.yaml

version: "3.9"

services:
  web:
    build:
      context: .
    environment:
      DATABASE_URL: file:./prisma/dev.db
    ports:
      - 3000:3000
    volumes:
      - /app/prisma
      - .:/app
      - /app/node_modules

My prisma stuff lives in the root-dir/prisma. In there I have:
prisma/dev.db
prisma/schema.prisma
prisma/migrations/20231227173804_intial_migration

I tried running a cache free re build of my docker image and also tried the prisma generate with and without the specific --schema flag.

How do I get this to run my docker container using docker compose up?

Thanks.

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out. I had an permissions issue that caused the prisma, dev.db files/dirs to be owned by root instead of the app user I am appointing in my Dockerfile. I also needed to re-run a docker compose command and exclude cache so it didn't use previous configurations.

    Updated:

    Dockerfile

    # set the base image to create the image for react app
    FROM node:20-alpine
    
    # create a user with permissions to run the app
    # -S -> create a system user
    # -G -> add the user to a group
    # This is done to avoid running the app as root
    # If the app is run as root, any vulnerability in the app can be exploited to gain access to the host system
    # It's a good practice to run the app as a non-root user
    RUN addgroup app && adduser -S -G app app
    
    # set the user to run the app
    USER app
    
    # set the working directory to /app
    WORKDIR /app
    
    # copy package.json and package-lock.json to the working directory
    # This is done before copying the rest of the files to take advantage of Docker’s cache
    # If the package.json and package-lock.json files haven’t changed, Docker will use the cached dependencies
    COPY package*.json ./
    COPY ./prisma prisma
    COPY ./dev.db /app/dev.db
    
    # sometimes the ownership of the files in the working directory is changed to root
    # and thus the app can't access the files and throws an error -> EACCES: permission denied
    # to avoid this, change the ownership of the files to the root user
    USER root
    
    # Ensure write permissions for the app directory and its contents
    RUN chmod -R u+w .
    
    # change the ownership of the /app directory to the app user
    # chown -R <user>:<group> <directory>
    # chown command changes the user and/or group ownership of for given file.
    RUN chown -R app:app .
    
    # As root, change the ownership of dev.db to app user
    RUN chown app:app dev.db
    
    # change the user back to the app user
    USER app
    
    # init prisma
    RUN npx prisma generate --schema=./prisma/schema.prisma
    
    # install dependencies
    RUN npm install
    
    # copy the rest of the files to the working directory
    COPY . .
    
    # expose port 3000 to tell Docker that the container listens on the specified network ports at runtime
    EXPOSE 3000
    
    # command to run the app
    CMD npm run dev
    

    compose.yaml

    version: "3.9"
    
    services:
      web:
        build:
          context: .
        environment:
          DATABASE_URL: file:./dev.db
        ports:
          - 3000:3000
        volumes:
          - /app/prisma
          - ./dev.db:/app/dev.db:rw # Mount the database file with correct ownership
          - .:/app
          - /app/node_modules
    
    

    Commands:

    1. docker-compose build --no-cache
    2. docker compose up

    After this, I was able to write to my sqlite db with prisma orm inside of a Docker container.


Please signup or login to give your own answer.
Back To Top
Search