Assist_Design/docs/guides/docker-prisma.md

123 lines
3.0 KiB
Markdown
Raw Normal View History

# 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)