- 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.
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 |