- Streamlined the README.md for clarity and conciseness. - Deleted outdated documentation files related to Freebit SIM management, SIM management API data flow, and various architectural guides to reduce clutter and improve maintainability. - Updated the last modified date in the README to reflect the latest changes.
138 lines
3.2 KiB
Markdown
138 lines
3.2 KiB
Markdown
# 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:
|
|
|
|
```javascript
|
|
// Inside generated client (simplified)
|
|
const config = {
|
|
schemaPath: "prisma/schema.prisma", // embedded at generate time
|
|
// ...
|
|
};
|
|
```
|
|
|
|
### 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
|
|
|
|
In production, the schema is at:
|
|
|
|
```
|
|
prisma/schema.prisma
|
|
```
|
|
|
|
## The Solution
|
|
|
|
Regenerate the Prisma client **from the production directory layout** before creating the final image:
|
|
|
|
```dockerfile
|
|
# After pnpm deploy creates the bundle at /app (final layout)
|
|
WORKDIR /app
|
|
RUN pnpm dlx prisma@${PRISMA_VERSION} generate --schema=prisma/schema.prisma
|
|
```
|
|
|
|
This regenerates the client with:
|
|
|
|
```javascript
|
|
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:
|
|
|
|
```dockerfile
|
|
RUN pnpm dlx prisma@${PRISMA_VERSION} generate --schema=prisma/schema.prisma
|
|
```
|
|
|
|
### 3. Match Prisma Versions
|
|
|
|
Ensure the version in Docker matches `package.json`:
|
|
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"@prisma/client": "7.1.0"
|
|
},
|
|
"devDependencies": {
|
|
"prisma": "7.1.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. Include Binary Targets
|
|
|
|
Always include the production binary target in schema:
|
|
|
|
```prisma
|
|
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:
|
|
|
|
```bash
|
|
cat node_modules/.prisma/client/index.js | grep schemaPath
|
|
```
|
|
|
|
### Verify Schema Location
|
|
|
|
In the container:
|
|
|
|
```bash
|
|
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
|
|
|
|
- [Prisma with pnpm](https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/prisma-client-pnpm)
|
|
- [Prisma Docker Best Practices](https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/deployment)
|