skip to Main Content

I have a Docker container serving a Postgres database on port 5432. I am now attempting to build another container that uses the Prisma Client to access the database. However, to be able to build the project I first need to introspect the database to create the schema and then generate the Prisma Client. This is how my Dockerfile looks:

FROM node:16-alpine

WORKDIR /site

COPY package*.json .

RUN npm ci

COPY . .

RUN npx prisma db pull # introspect the database

RUN npx prisma generate # generate prisma client

RUN npm run build # build project

EXPOSE 3000

CMD ["node", "-r", "dotenv/config", "build"]

The issue is that the Docker build context can’t connect to the database through the usual URL:

DATABASE_URL=postgresql://postgres:mypassword@localhost:5432/postgres

The error I get is the following:

 > [site 6/8] RUN npx prisma db pull:
#0 1.756 Prisma schema loaded from prisma/schema.prisma
#0 1.759 Environment variables loaded from .env
#0 1.764 Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"
#0 1.769
#0 1.773 - Introspecting based on datasource defined in prisma/schema.prisma
#0 1.818 ✖ Introspecting based on datasource defined in prisma/schema.prisma
#0 1.818
#0 1.819 Error: P1001
#0 1.819
#0 1.819 Can't reach database server at `localhost`:`5432`
#0 1.819
#0 1.819 Please make sure your database server is running at `localhost`:`5432`.
#0 1.819

I also tried creating a Docker network to connect both containers but this doesn’t work as the Docker build context doesn’t connect to the network, only the running container would.

I know that usually database commands are run only when the container starts, but I don’t think that is an option as I need to run them to be able to build my project. What should I do?

2

Answers


  1. You can create a docker compose for this POC.

    version: "3.9"
    services:
      nodeweb:
        build: .
        ports:
          - "8000:8000"
      db:
        image: postgres
        ports:
          - "8001:5432"
    

    Then use endpoint db:
    DATABASE_URL=postgresql://postgres:mypassword@db:5432/postgres

    Login or Signup to reply.
  2. There’s no need to overcomplicate your build process by introspecting your database in the dockerfile. I don’t see any reason why you would want to do that. What you should be doing is :

    1. introspecting your db locally when you’re developing
    2. generate the client and verify your prisma.schema is correct
    3. push your schema to your source control (Github or whatever you use) so you keep track of any schema changes
    4. then when you’re ready to deploy, simply copy the prisma schema and run prisma generate during the build in your dockerfile.

    By introspecting your DB during the build process you will run into errors because you have not validated whether the introspected prisma.schema is correct or not, nor is the schema tracked in source control. Anyone could make any changes within the db which won’t be tracked in your source control, resulting in disconnect between your source when you last generated the client during development and whatever state the db happens to be in at the time of the build.

    An example dockerfile :

    FROM node:16-alpine
    
    WORKDIR /site
    
    COPY package*.json .
    
    RUN npm ci
    
    COPY . . 
    
    COPY ./database/myschema.prisma ./database/myschema.prisma
    
    RUN npx prisma generate --schema ./database/myschema.prisma
    
    RUN npm run build # build project
    
    EXPOSE 3000
    
    CMD ["node", "-r", "dotenv/config", "build"]
    

    Edit :

    I want to add, I think you’re fundamentally misunderstanding Prisma and how to use it. The whole point of Prisma is to keep track of your prisma.schema in your source control, as well as any prisma migrations that you do when you change your db schema. Introspecting your DB to generate the prisma.schema is just a tool, one that I recommend you only do once initially if you already have an existing database schema, and not anytime thereafter.

    Your workflow should be :

    1. Introspect your DB to create the initial prisma.schema. You should only do this once initially.

    2. Make any changes to your database schema by modifying the prisma.schema, not modifying your database directly. Any new tables, new relationships, new columns or any other modification you want to do, you should be modifying the prisma.schema and then run prisma migrate, not modifying your database directly. That’s the whole point of a ORM.

    3. Push any changes you make to your prisma schema as well as any migration files that are automatically generated when you prisma migrate to your source control, so you keep track of any changes to your database schema, and so that anyone else working on your project can pull the schema changes.

    4. When building simply copy the prisma.schema to your container and run prisma generate, like the example I provided above.

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