Assist_Design/docs/guides/docker-prisma.md
barsa 29ad4236d6 Enhance development scripts and update package dependencies
- Added a new script command `dev:studio` to facilitate studio management in development.
- Updated the Prisma dependency in BFF package to version 6.16.0 for improved features and bug fixes.
- Refactored Dockerfiles for BFF and Portal to enhance health check mechanisms during startup.
- Removed deprecated WhmcsApiMethodsService to streamline the integration services.
- Cleaned up various components and services in the SIM management module for better maintainability and clarity.
2025-12-02 18:56:38 +09:00

3.2 KiB

Docker & Prisma in Monorepos

The Challenge

When using Prisma in a pnpm monorepo with Docker, there's a common pitfall related to how Prisma embeds file paths.

Understanding the Problem

1. Prisma Embeds Schema Paths

When you run prisma generate, Prisma creates a client at node_modules/.prisma/client/ and embeds the schema path as metadata:

// Inside generated client (simplified)
const config = {
  schemaPath: "apps/bff/prisma/schema.prisma",  // ← This path is embedded!
  // ...
}

2. Monorepo vs Production Directory Structures

During Build (Monorepo):

/app/
├── apps/
│   └── bff/
│       ├── prisma/schema.prisma   ← Schema here
│       └── src/
├── packages/
└── pnpm-workspace.yaml

In Production (After pnpm deploy):

/app/
├── prisma/schema.prisma           ← Schema moved to root!
├── dist/
└── node_modules/

3. The Mismatch

The generated Prisma client still contains:

schemaPath: "apps/bff/prisma/schema.prisma"

But in production, the schema is at:

prisma/schema.prisma

This causes errors like:

Error: Could not load `--schema` from provided path `apps/bff/prisma/schema.prisma`: file or directory not found

The Solution

Regenerate the Prisma client from the production directory layout before creating the final image:

# After pnpm deploy creates the bundle at /app (final layout)
WORKDIR /app
RUN npx prisma@6.16.0 generate --schema=prisma/schema.prisma

This regenerates the client with:

schemaPath: "prisma/schema.prisma"  // ← Matches production!

Best Practices

1. Document the Behavior

Add comments in Dockerfile and schema.prisma explaining why regeneration is needed.

2. Version Lock Prisma

Use explicit version in Docker:

RUN npx prisma@6.16.0 generate --schema=prisma/schema.prisma

3. Match Prisma Versions

Ensure the version in Docker matches package.json:

{
  "dependencies": {
    "@prisma/client": "^6.16.0"
  },
  "devDependencies": {
    "prisma": "^6.16.0"
  }
}

4. Include Binary Targets

Always include the production binary target in schema:

generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}

Debugging

Check Embedded Path

You can inspect the generated client's config:

cat node_modules/.prisma/client/index.js | grep schemaPath

Verify Schema Location

In the container:

ls -la /app/prisma/schema.prisma

Common Errors

Error Cause Fix
Could not load --schema from path Embedded path doesn't match actual location Regenerate from production structure
Prisma Client not found Client not generated or not copied Run prisma generate in Dockerfile
Query engine not found Missing binary target Add correct binaryTargets to schema

Further Reading