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