WSの小屋

Prisma 不同平台的部署

Prisma 是一个优秀的 Node.js/TypeScript ORM,但在部署时有一个常见陷阱:Prisma Client 会根据运行平台生成对应的查询引擎二进制文件,如果本地开发环境和服务器的操作系统不同,就会导致部署后运行报错。

本文会详细分析问题原因并给出几种解决方案。

问题现象

项目中使用 Prisma,通过 GitHub Actions 打包部署后,运行时报错:

Invalid `prisma.queryRaw()` invocation:
Query engine binary for current platform "linux" could not be found.

这是因为在 Windows/macOS 上打包时,Prisma 只生成了对应平台的引擎文件。

解决方案

方案一:在目标环境打包(推荐)

最简单的做法是在服务器的目标环境内执行打包和部署:

使用 Docker 多阶段构建:

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma
RUN npm ci
RUN npx prisma generate          # 在构建阶段生成引擎
RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=builder /app ./
EXPOSE 3000
CMD ["node", "dist/main.js"]

这样 Prisma 会在 Alpine Linux 环境下生成对应平台的引擎文件。

方案二:配置 binaryTargets(灵活方案)

schema.prisma 中显式声明需要支持的平台:

generator client {
  provider        = "prisma-client-js"
  binaryTargets   = ["native", "linux-musl", "linux-debian-openssl-3.0-x86_64"]
}

参数说明:

  • native:当前运行平台的引擎(开发环境使用)
  • linux-musl:Alpine Linux 使用的 musl 库
  • linux-debian-openssl-3.0-x86_64:Debian/Ubuntu 系统的引擎

设置后执行:

npx prisma generate

Prisma 会同时生成多个平台的引擎文件,打包时包含所有目标平台。

方案三:Prisma CLI 在服务器安装时生成

在部署脚本中添加:

# package.json scripts
{
  "postinstall": "prisma generate",
  "build": "prisma generate && tsc"
}

这样每次安装依赖时都会根据当前平台重新生成 Prisma Client。

方案四:使用 Prisma 的引擎缓存

Prisma 支持通过环境变量指定引擎文件路径:

# .env
PRISMA_QUERY_ENGINE_BINARY=/path/to/query-engine
PRISMA_SCHEMA_ENGINE_BINARY=/path/to/schema-engine

可以将预编译的引擎文件打包到项目中使用。

GitHub Actions 部署示例

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 18
      - run: npm ci
      - run: npx prisma generate
      - run: npm run build
      - run: npx prisma migrate deploy   # 数据库迁移
      # 部署到服务器...

常见问题排查

问题 原因 解决
Invalid platform 目标平台与生成的引擎不匹配 添加对应平台的 binaryTarget
Cannot find module @prisma/client Prisma Client 未生成 运行 prisma generate
OpenSSL 版本不匹配 系统 OpenSSL 版本不同 在 binaryTargets 指定正确的 OpenSSL 版本

总结

Prisma 跨平台部署的关键在于理解查询引擎的生成机制。推荐使用 Docker 构建binaryTargets 配置 两种方式,前者简单可靠,后者灵活可控。根据实际场景选择最适合的方案即可。

Comments | 0条评论