Next.js + Prisma 跨平台部署踩坑记

从 Windows 到 Linux 的完整解决方案

摘要:本文记录了一个 Next.js 16 + Prisma 6 项目从 Windows 开发环境部署到 Linux 生产环境时遇到的 Prisma Client 二进制文件不兼容、Turbopack 构建错误、依赖安装问题等一系列挑战,以及最终的解决方案。


背景

项目技术栈:

  • 前端框架:Next.js 16.2.9(使用 Turbopack)
  • ORM:Prisma 6.19.3
  • 数据库:MySQL
  • 开发环境:Windows
  • 生产环境:Linux (Debian OpenSSL 3.0.x)

问题一:Prisma Client 找不到 Query Engine

错误信息

复制代码
Prisma Client could not locate the Query Engine for runtime "debian-openssl-3.0.x".

This happened because Prisma Client was generated for "windows", but the actual 
deployment required "debian-openssl-3.0.x".

The following locations have been searched:
  /www/jianli/node_modules/.prisma/client
  /www/jianli/node_modules/@prisma/client
  E:\develop\project\generate-resume\node_modules\@prisma\client
  /tmp/prisma-engines

原因分析

Prisma Client 包含平台特定的二进制文件(Query Engine),用于执行数据库查询。这个二进制文件是在运行 prisma generate 时根据当前操作系统生成的。

关键问题

  1. 在 Windows 上执行 prisma generate 生成的是 Windows 版本的 .exe 文件
  2. 将生成的 node_modules 直接上传到 Linux 服务器
  3. Linux 无法执行 Windows 的二进制文件

解决方案

第一步:配置多平台支持

lib/db/prisma/schema.prisma 中添加 binaryTargets

prisma 复制代码
generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "debian-openssl-3.0.x"]
}
  • native:当前开发环境的二进制文件(Windows)
  • debian-openssl-3.0.x:目标 Linux 环境的二进制文件

第二步:在目标服务器上重新生成

错误的做法 :在 Windows 上生成后上传 node_modules

正确的做法 :在 Linux 服务器上执行 prisma generate

bash 复制代码
cd /www/jianli
npx prisma generate --schema=./lib/db/prisma/schema.prisma

注意 :Prisma 6.x 对 prisma.config.ts 的支持有限,需要显式指定 --schema 参数,或者在 package.json 中配置:

json 复制代码
{
  "prisma": {
    "schema": "./lib/db/prisma/schema.prisma"
  }
}

问题二:Standalone 模式与 Turbopack 不兼容

错误信息

复制代码
Error [ChunkLoadError]: Failed to load chunk server/chunks/ssr/node_modules_next_dist_0uboya6._.js
Cannot find module '/www/jianli/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js'

静态资源返回 500 或 404:

复制代码
/_next/static/chunks/xxx.css → 500 Internal Server Error

原因分析

Next.js 的 output: "standalone" 模式旨在生成最小化的生产构建,只包含运行时必需的文件。但与 Turbopack(Next.js 16 默认编译器)存在兼容性问题:

  1. standalone 目录结构不完整:缺少必要的 SSR chunk 文件
  2. 静态资源路径映射错误.next/static 目录未被正确复制到 standalone 目录
  3. 模块解析失败:Turbopack 生成的 chunk 文件名与运行时期望的不匹配

解决方案

暂时禁用 standalone 模式,使用标准 Next.js 部署方式:

typescript 复制代码
// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // output: "standalone", // 因 Turbopack 兼容性问题暂时禁用
};

export default nextConfig;

启动命令改为:

bash 复制代码
pm2 start npm --name jianli -- start -- -p 3000

提示 :如果必须使用 standalone 模式,可以考虑切换回 Webpack 编译器(设置 turbopack: false),但这会牺牲构建速度。


问题三:npm install 跳过 devDependencies

错误信息

复制代码
Error: Cannot find module '@tailwindcss/postcss'
Require stack:
- /www/jianli/.next/build/chunks/[root-of-the-server]__0oj80bi._.js

原因分析

Tailwind CSS v4 使用 @tailwindcss/postcss 作为 PostCSS 插件,该包位于 devDependencies 中。

部署脚本中设置了 NODE_ENV=production

bash 复制代码
export NODE_ENV=production
npm install --omit=dev  # 或 npm install --production

这导致 npm 跳过了 devDependencies 的安装,但 Next.js 构建过程需要这些开发依赖

解决方案

在安装依赖前取消 NODE_ENV 设置:

bash 复制代码
#!/bin/bash
set -e
cd /www/jianli

# 先 unset NODE_ENV,确保安装所有依赖(包括 devDependencies)
unset NODE_ENV && npm install 2>&1

# 构建完成后,再设置 NODE_ENV 为 production
export NODE_ENV=production
npx next build 2>&1

# 启动时也使用 production 模式
NODE_ENV=production pm2 start npm --name jianli -- start -- -p 3000

问题四:Prisma 6.x schema 路径配置

错误信息

复制代码
Could not load schema from `lib\db\prisma\schema.prisma`

原因分析

Prisma 6.x 引入了新的 prisma.config.ts 配置文件,但对它的支持尚不完善。CLI 命令可能无法自动读取配置文件中的 schema 路径。

解决方案

方案一 :在所有 Prisma 命令中显式指定 --schema 参数

bash 复制代码
npx prisma generate --schema=./lib/db/prisma/schema.prisma
npx prisma db push --schema=./lib/db/prisma/schema.prisma
npx prisma migrate dev --schema=./lib/db/prisma/schema.prisma

方案二 :在 package.json 中配置默认 schema 路径

json 复制代码
{
  "prisma": {
    "schema": "./lib/db/prisma/schema.prisma"
  }
}

方案三:迁移到 Prisma 7.x(推荐长期方案)

Prisma 7 改进了配置文件支持,但需要注意这是一个 major version 升级,需要遵循官方迁移指南。


关键经验总结

问题 根本原因 解决方案
Prisma Query Engine 缺失 跨平台二进制文件不兼容 在目标平台重新 generate
Standalone 模式失败 Turbopack 兼容性 禁用 standalone,使用标准模式
缺少 @tailwindcss/postcss NODE_ENV=production 跳过 devDeps 安装前 unset NODE_ENV
Schema 路径找不到 Prisma 6.x 配置支持有限 显式指定 --schema 参数

给类似场景的建议

  1. 尽量在目标平台上构建:避免跨平台二进制文件问题,考虑使用 CI/CD 在 Linux 环境中构建

  2. 谨慎使用 standalone 模式:特别是配合 Turbopack 时,建议等待官方修复或使用 Webpack

  3. 区分构建时和运行时依赖 :确保构建时有所有需要的包,不要过度使用 --omit=dev

  4. 部署脚本模块化:将复杂命令拆分为独立的 shell 脚本,便于维护和调试

  5. 保留必要的日志输出:每步输出明确的状态信息,方便排查问题

  6. Prisma 最佳实践

    • 始终在目标平台执行 prisma generate
    • 使用 binaryTargets 配置多平台支持
    • 显式指定 schema 路径避免歧义

参考资料

相关推荐
专业抄代码选手6 小时前
08|Fiber 上的 `useState`:状态终于属于具体组件
前端·javascript·react.js
默_笙6 小时前
😭 Vibe Coding 翻车实录:AI 编程为什么必须先写"剧本"
前端·javascript
lerhxx7 小时前
我用 R3F 手搓了一个能走进去的 3D 迷宫简历(上):从选型架构到迷宫生成算法
前端·javascript·three.js
鹏多多12 小时前
PC 网站接入微信登录,这 10 个坑我替你踩完了!
前端·javascript·vue.js
用户2986985301413 小时前
React 中 HTML 内容转 Word 文档的实现方案
javascript·react.js·html
mONESY13 小时前
我用 Next.js 16 + Supabase 从零做了个「背单词」H5 应用
javascript
boooooooom13 小时前
手把手做一个图 RAG 烹饪问答系统:Neo4j + Milvus + LLM 的工程实践
前端·javascript·后端
Interview Aid11215 小时前
TikTok OA 四题分享|半小时内 AC,题目基本都是实现题
java·开发语言·算法·面试·职场和发展
染指111016 小时前
103.RAG-LLamaIndex后端rag问答-聊天接口
前端·javascript·vue.js·人工智能
CoderIsArt1 天前
C#中UI 线程与 Dispatcher
开发语言·ui·c#