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
I figured it out. I had an permissions issue that caused the prisma, dev.db files/dirs to be owned by
root
instead of theapp
user I am appointing in myDockerfile
. I also needed to re-run a docker compose command and exclude cache so it didn't use previous configurations.Updated:
Dockerfile
compose.yaml
Commands:
docker-compose build --no-cache
docker compose up
After this, I was able to write to my sqlite db with prisma orm inside of a Docker container.
I did it in a different but more secure way for Drizzle + SQLite + Next.js. I think the use is same for Prisma although this solution is probably closer except he uses Nest JS.