2026全栈生存指南:我用 Next.js + Prisma 7 + DeepSeek 做了个 AI 记账本,部署时踩了 10 个坑

0 阅读4分钟

摘要:
本来以为是简单的 CRUD,结果差点死在 Docker 部署上。本文记录了一个全栈 AI 应用从 0 到 1 的完整过程,重点复盘 Next.js Standalone 模式下的 Prisma 迁移、DeepSeek 集成以及 Docker 多阶段构建的血泪史。附最终完美运行的 Dockerfile 和 Compose 配置。

🎙️ 前言

现在是 2026 年,全栈开发的门槛看似降低了,但“陷阱”却更加隐蔽了。
最近心血来潮,想做一个**“CashFlow AI 智能记账本”**。技术栈选型极其现代化:

  • 框架:Next.js 16 (App Router)
  • 数据库:Prisma 7 + SQLite (本地) / PostgreSQL (生产)
  • AI:DeepSeek V3 (国产之光)
  • 部署:Docker Compose + 自建 VPS

本来以为两天搞定,结果在部署环节硬生生卡了三天(可能是我比较菜)。今天把这些坑填平了,整理出来,希望后人不要再踩。


🕳️ 坑位一:Prisma 7 的“精神分裂”与 P1012 报错

现象:
在 Prisma 7 中,为了支持 Serverless 环境,官方不再建议在 schema.prisma 里直接写数据库 URL。于是我配置了 prisma.config.ts。
结果本地开发好好的,一上 Docker 就报 P1012,或者报 datasources property unknown。

避坑指南:
在 Docker/VPS 这种 Node.js 原生环境下,千万别整那些花里胡哨的 Adapter(适配器模式)。

  1. 删掉 prisma.config.ts。
  2. 回归 schema.prisma 里的 url = env("DATABASE_URL")。
  3. 代码里直接 new PrismaClient(),零参数启动。
    结论:  简单的才是最稳的。

🕳️ 坑位二:DeepSeek 集成时的 Vercel SDK 404

现象:
使用 Vercel AI SDK 集成 DeepSeek 时,直接报错 404 Not Found 或者 response_format unavailable。原因是 SDK 默认拼接的路径 DeepSeek 不认,或者 SDK 强制要求的 JSON Mode 参数 DeepSeek 暂时不支持。

避坑指南:

  1. 手动挡最稳:不要用 generateObject 这种魔法方法,改用 generateText。
  2. Prompt 工程:在 System Prompt 里强行要求 AI 输出纯 JSON,然后在代码里 JSON.parse。
  3. 超时控制:国内网络环境波动大,务必在 fetch 中注入 AbortController,把超时时间拉长到 60s。

🕳️ 坑位三:Next.js Standalone 模式“扔掉了”我的 Prisma

这是最大的坑,卡了我整整一天。

现象:
Docker 构建成功了,但运行 prisma migrate deploy 时报错:Cannot find module 'prisma/config'。

原因:
Next.js 的 output: "standalone" 模式非常智能,打包时会自动分析依赖,把没用到的包扔掉。
不幸的是,我们的业务代码只引用了 @prisma/client,没引用 prisma CLI 工具。所以 Prisma CLI 被 Next.js 当作垃圾扔掉了

避坑指南(终极 Dockerfile 写法):
必须在 Dockerfile 的最后阶段,手动把被扔掉的包拷回来,或者强行安装。
最优雅的解法是:把 prisma 包从 devDependencies 移到 dependencies,这样 Next.js 就会乖乖把它打包进去了。


🕳️ 坑位四:Docker 多阶段构建找不到 pnpm

现象:
构建时报错 /bin/sh: pnpm: not found。

原因:
我在 deps 阶段装了 pnpm,以为全局通用。但 Docker 的多阶段构建(Multi-stage)是隔离的,builder 阶段并不继承 deps 阶段的全局工具。

避坑指南:
把 npm install -g pnpm 放到最基础的 base 镜像阶段,一劳永逸。


🏆 最终成果:完美的架构方案

经过无数次报错(ENOTFOUND, ERESOLVE, P1001...),我总结出了一套**“生产级”**的部署配置。

1. 完美的 Dockerfile

支持国内镜像源、支持 lock 文件一致性校验、支持 Prisma 迁移。

codeDockerfile

FROM node:20-alpine AS base
WORKDIR /app
# 关键:在这里装 pnpm,所有阶段都能用
RUN npm install -g pnpm

# 1. 依赖阶段
FROM base AS deps
RUN npm config set registry https://registry.npmmirror.com
COPY package.json pnpm-lock.yaml* ./
# 关键:使用 --no-frozen-lockfile 允许自动修复锁文件冲突
RUN pnpm install --no-frozen-lockfile

# 2. 构建阶段
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# 注入假 URL 骗过 Prisma 生成检查
ENV DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy"
RUN pnpm prisma generate
RUN pnpm build --no-lint

# 3. 运行阶段
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# ... (用户权限配置略)

# 关键:把 Prisma 的配置文件手动拷进去
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
# ... (其他 COPY 略)

CMD ["node", "server.js"]

2. 优雅的 Docker Compose 编排

这里有一个架构上的升华
不要在 App 容器里手动跑迁移,也不要手动 exec。
我们引入一个专门的 migrate 容器(工程车),利用 depends_on 和 healthcheck 实现自动化流水线。

codeYaml

version: "3.9"
services:
  db:
    image: postgres:15-alpine
    # ... (配置略)
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      retries: 5

  # 专门负责建表的"工程车"
  migrate:
    build:
      context: .
      target: builder # 关键:使用 builder 阶段的镜像,环境全
    command: npx prisma migrate deploy
    depends_on:
      db:
        condition: service_healthy

  # 真正的应用
  app:
    build: .
    depends_on:
      migrate:
        condition: service_completed_successfully # 等表建好了再启动
    # ...

🔚 总结

全栈开发不仅仅是写代码,环境治理部署架构往往占了 50% 的难度。
这三天的折腾,虽然掉了不少头发,但换来了:

  1. 一套极低成本的 AI SaaS 架构(0 元数据库,0 元部署)。
  2. 对 Next.js 构建机制的深度理解
  3. 一套可复用的工业级 Docker 配置