What started as a simple Prisma upgrade became a deep dive into Docker architecture, WebAssembly file handling, and TypeScript path resolution. Here's our complete journey from 7.2.0 to 7.5.0.

Upgrading to Prisma 7.5.0: A Complete Docker and WASM Troubleshooting Guide

Published: March 24, 2026
Category: Technical, Docker, Node.js, Database

Introduction

Upgrading dependencies should be straightforward, right? That’s what I thought when we decided to upgrade our NestJS application from Prisma 7.2.0 to 7.5.0. What followed was a deep dive into Docker architecture, WebAssembly (WASM) file handling, and TypeScript path resolution that taught us valuable lessons about modern web development tooling.

This post chronicles our complete journey from a simple version bump to a production-ready deployment, including every obstacle we encountered and how we solved them.

The Starting Point

Our tech stack:

  • Backend: NestJS with TypeScript
  • Database: PostgreSQL with Prisma ORM
  • Deployment: Docker multi-stage builds
  • Target Environment: AWS AL2023 (Amazon Linux 2023)

Everything was working smoothly with Prisma 7.2.0, and we wanted to upgrade to 7.5.0 for the latest features and improvements.

Phase 1: The Simple Version Bump

Initial Attempt

npm install prisma@7.5.0 @prisma/client@7.5.0

Simple enough, right? Wrong. Immediately after the upgrade, we hit our first roadblock.

Error #1: Schema Configuration Changes

Error: The `url` field in the datasource block is no longer supported in Prisma 7.5.0.

Problem: Prisma 7.5.0 moved the database URL from the schema file to the configuration.

Solution: Updated our schema files:

// Before (schema.prisma)
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// After (schema.prisma)  
datasource db {
  provider = "postgresql"
}

// And in prisma.config.ts
export default defineConfig({
  schema: 'prisma/schema.prisma',
  datasource: {
    url: env('DATABASE_URL'),
  },
});

This change affected both our main schema and our control-plane schema, requiring updates to multiple configuration files.

Phase 2: The Docker Build Nightmare

Error #2: Binary Target Mismatch

With the schema fixed, we attempted our Docker build:

docker build -f backend/Dockerfile .

And immediately hit:

Error: Cannot find query engine for current platform "linux-openssl-3.0.x"

Problem: Prisma 7.5.0 introduced new binary targets, and our existing debian-openssl-3.0.x target wasn’t compatible with AWS AL2023.

Solution: Updated our binary targets:

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

The key insight was that AL2023 is based on RHEL, not Debian, so we needed the rhel-openssl-3.0.x target.

Error #3: Docker File Structure Issues

Even with the correct binary targets, we encountered:

ERROR in main
Module not found: Error: Can't resolve '/app/backend/src/src/main.ts'

Problem: Our Dockerfile was using COPY ./backend ./ which created a nested directory structure that confused Webpack.

Solution: Restructured our Dockerfile copies:

# Before (causing double path)
COPY ./backend/prisma ./prisma
COPY ./backend ./

# After (direct structure)
COPY ./backend/prisma ./prisma/
COPY ./backend/src ./src/
COPY ./backend/tsconfig.json ./
COPY ./backend/nest-cli.json ./
COPY ./backend/prisma*.ts ./
COPY ./backend/config ./config/

This ensured files were copied directly to /app/ rather than /app/backend/.

Phase 3: The WASM Import Crisis

Error #4: WebAssembly Files Missing

The Docker build succeeded, but at runtime we hit the critical error:

Error: Cannot find module './query_compiler_fast_bg.wasm'

Problem: Prisma 7.5.0 uses WebAssembly for query compilation, but Webpack was stripping these files during the build process.

Solution: Manual WASM file preservation in Dockerfile:

# Generate Prisma client
RUN npx prisma generate
RUN npx prisma generate --schema ./prisma/control-plane/schema.prisma

# Build the application
RUN npm run build

# Manually copy WASM files to prevent Webpack from stripping them
RUN cp -r node_modules/.prisma/client/*.js node_modules/.prisma/client/*.wasm ./dist/ 2>/dev/null || true
RUN cp -r src/generated/prisma/runtime/*.js src/generated/prisma/runtime/*.wasm ./dist/src/generated/prisma/runtime/ 2>/dev/null || true
RUN cp -r src/generated/control-plane/runtime/*.js src/generated/control-plane/runtime/*.wasm ./dist/src/generated/control-plane/runtime/ 2>/dev/null || true

We also updated our nest-cli.json to include these assets:

{
  "compilerOptions": {
    "webpack": true,
    "assets": [
      {
        "include": "generated/prisma/**/*",
        "outDir": "dist/src",
        "watchAssets": true
      }
    ]
  }
}

Phase 4: TypeScript Path Resolution

Error #5: Import Path Changes

Even with WASM files present, we encountered:

Module not found: Error: Can't resolve '@/generated/prisma/client'

Problem: Prisma 7.5.0 changed how the client is exported. The separate client.js file now just re-exports from the main index.js.

Solution: Updated TypeScript path mappings:

{
  "compilerOptions": {
    "paths": {
      "@/*": ["src/*"],
      "@/generated/prisma": ["src/generated/prisma"],
      "@/generated/prisma/client": ["src/generated/prisma"]
    }
  }
}

The key insight was that @/generated/prisma/client should point to the main index, not a separate client file.

Phase 5: Local Development Issues

Error #6: NestJS Entry Point Problems

Back in local development, we hit:

ERROR in main
Module not found: Error: Can't resolve '/Users/xoxo/Projects/stock-picker/backend/src/src/main.ts'

Problem: Our package.json scripts were using --entryFile src/main which confused Webpack’s path resolution.

Solution: Simplified the scripts:

{
  "scripts": {
    "start": "nest start",
    "start:dev": "nest start --watch", 
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main"
  }
}

NestJS automatically finds the entry point when not explicitly specified.

Phase 6: Production Runtime

Error #7: Incorrect Production Path

Finally, in Docker production:

Error: Cannot find module '/app/dist/src/main'

Problem: The start:prod script was looking for dist/src/main but NestJS builds to dist/main.

Solution: Fixed the production script:

{
  "start:prod": "node dist/main"
}

The Complete Solution

Here’s our final working configuration:

Dockerfile Key Changes

# Use Node 20 (required for Prisma 7.5.0)
FROM node:20-bookworm AS node-builder

# Install OpenSSL dependencies for AL2023 compatibility
RUN apt-get update && apt-get install -y \
    build-essential \
    python3 \
    make \
    g++ \
    libssl-dev \
    libvips-dev \
    && rm -rf /var/lib/apt/lists/*

# Copy files directly (no nested structure)
COPY ./backend/package*.json ./
RUN npm ci
COPY ./backend/prisma ./prisma/
COPY ./backend/src ./src/
COPY ./backend/tsconfig.json ./
COPY ./backend/nest-cli.json ./
COPY ./backend/prisma*.ts ./
COPY ./backend/config ./config/

# Generate and build
RUN npx prisma generate
RUN npx prisma generate --schema ./prisma/control-plane/schema.prisma
RUN npm run build

# Preserve WASM files
RUN cp -r node_modules/.prisma/client/*.js node_modules/.prisma/client/*.wasm ./dist/ 2>/dev/null || true

Package.json Scripts

{
  "scripts": {
    "build": "nest build",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch", 
    "start:prod": "node dist/main"
  }
}

TypeScript Configuration

{
  "compilerOptions": {
    "paths": {
      "@/*": ["src/*"],
      "@/generated/prisma": ["src/generated/prisma"],
      "@/generated/prisma/client": ["src/generated/prisma"]
    }
  }
}

Prisma Schema

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

datasource db {
  provider = "postgresql"
}

Lessons Learned

1. Dependency Upgrades Are Never Simple

What starts as a simple version bump can uncover architectural assumptions and dependencies you didn’t know existed.

2. WebAssembly Changes Everything

Prisma’s move to WASM for query compilation introduced new deployment considerations that didn’t exist with pure JavaScript.

3. Docker File Structure Matters

How you copy files in Docker affects not just the build but also how Webpack resolves modules at runtime.

4. Binary Targets Are Platform-Specific

The move from Debian to RHEL-based targets for AL2023 was crucial and not immediately obvious.

5. TypeScript Path Mappings Need Updates

Library changes can affect how modules are exported, requiring path mapping adjustments.

Verification Checklist

After the upgrade, we verified everything worked:

  • Local development: npm run start:dev
  • Docker build: docker build -f backend/Dockerfile .
  • Docker runtime: docker-compose up platform-backend
  • API endpoints: curl http://localhost:8080/
  • Database connectivity: Prisma migrations applied
  • Market data ingestion: WebSocket connections active
  • No WASM errors in logs

Conclusion

The Prisma 7.5.0 upgrade taught us that modern web development tooling is increasingly complex, with interdependencies between Docker, Webpack, TypeScript, and WebAssembly that require careful coordination.

What seemed like a routine upgrade became a comprehensive audit of our build and deployment pipeline, ultimately making it more robust and better understood.

The key takeaway: always test dependency upgrades in a staging environment that closely mirrors production, and be prepared for unexpected interactions between different parts of your toolchain.

References


FAQ

Q: Why did Prisma move the database URL from schema.prisma to prisma.config.ts?

A: This change improves security and configuration flexibility. By moving the URL to the config file, you can use environment variables more effectively and avoid committing sensitive database URLs to version control. It also allows for more complex configuration scenarios like dynamic database URLs.

Q: What’s the difference between Debian and RHEL binary targets?

A: Debian targets (debian-openssl-3.0.x) are for Debian-based systems like Ubuntu, while RHEL targets (rhel-openssl-3.0.x) are for Red Hat Enterprise Linux and derivatives like CentOS, Fedora, and Amazon Linux 2023. The choice affects which OpenSSL libraries and system dependencies Prisma expects.

Q: Why do WASM files get stripped during the build process?

A: Webpack and other bundlers typically only include JavaScript files by default. WASM files (.wasm) are binary assets that need explicit handling. Without proper configuration, they’re treated as unused assets and removed during optimization.

Q: Can I avoid manually copying WASM files?

A: Yes, you can configure Webpack to handle WASM files automatically. Add a rule to your webpack configuration to copy .wasm files, or use the copy-webpack-plugin to include them in your build output.

Q: How do I know which binary target to use for my deployment environment?

A: Check your base Docker image or target OS. For AWS AL2023, use rhel-openssl-3.0.x. For Ubuntu/Debian, use debian-openssl-3.0.x. For macOS development, native works best. You can include multiple targets for compatibility.

Q: What if I’m still getting WASM errors after copying the files?

A: Ensure the WASM files are in the correct relative paths and that your application has permission to execute them. Also check that your Node.js version supports WebAssembly (Node.js 12+). Sometimes you need to set NODE_OPTIONS="--experimental-wasm-modules".

Q: Should I always include both “native” and platform-specific targets?

A: For local development, native is sufficient. For production deployments, include both native (for development/testing) and your specific platform target. This ensures compatibility across environments while keeping the bundle size reasonable.


Have you faced similar upgrade challenges? Share your experience in the comments below!

Welcome to The infinite monkey theorem

Somewhere a monkey just typed Shakespeare in TypeScript. Be the first to read the masterpieces (and the hilarious misfires) landing on the blog.

Subscribe to The infinite monkey theorem

We fling fresh posts—no banana peels attached—straight to your inbox.