Prisma+Docker+NextJS环境中npx prisma db push的放置位置咨询
解决Prisma + NextJS + Docker容器化时表不存在的问题
问题核心
npx prisma db push需要在数据库容器完全启动并可连接后执行,你之前在构建阶段执行该命令时,PostgreSQL容器还未运行,导致无法创建表,最终代码访问时提示表不存在。
解决方案:运行时初始化数据库
1. 创建初始化脚本
在项目根目录新建entrypoint.sh脚本,用于等待数据库就绪并执行表同步:
#!/bin/sh # 等待PostgreSQL服务就绪 until pg_isready -h myhost -p 5432 -U root; do echo "等待PostgreSQL启动..." sleep 2 done # 同步Prisma schema到数据库 npx prisma db push # 启动NextJS应用 node server.js
给脚本添加执行权限:
chmod +x entrypoint.sh
2. 修改Dockerfile
更新deploy阶段,添加数据库客户端依赖并替换启动命令为脚本:
FROM node:18 AS dependencies WORKDIR /app COPY package.json yarn.lock ./ RUN yarn FROM node:18 AS build WORKDIR /app COPY --from=dependencies /app/node_modules ./node_modules COPY . . RUN npx prisma generate RUN yarn build:in:docker FROM node:18 AS deploy WORKDIR /app ENV NODE_ENV production # 安装PostgreSQL客户端(用于pg_isready检查) RUN apt-get update && apt-get install -y postgresql-client && rm -rf /var/lib/apt/lists/* COPY --from=build /app/public ./public COPY --from=build /app/package.json ./package.json COPY --from=build /app/.next/standalone ./ COPY --from=build /app/.next/static ./.next/static COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/prisma ./prisma # 复制初始化脚本 COPY entrypoint.sh ./ EXPOSE 3000 ENV PORT 3000 # 使用脚本启动服务 ENTRYPOINT ["./entrypoint.sh"]
3. 优化docker-compose.yml
添加数据库健康检查,确保应用在数据库真正可用后再启动:
version: '3.9' services: postgres: image: postgres:latest container_name: postgres hostname: myhost ports: - 5432:5432 environment: POSTGRES_USER: root POSTGRES_PASSWORD: password POSTGRES_DB: splitmate volumes: - postgres-data:/var/lib/postgresql/data restart: unless-stopped # 健康检查:确认数据库可连接 healthcheck: test: ["CMD-SHELL", "pg_isready -U root -d splitmate"] interval: 5s timeout: 5s retries: 5 splitmate-app: image: splitmate build: context: . dockerfile: Dockerfile target: deploy # 依赖数据库的健康状态 depends_on: postgres: condition: service_healthy environment: DATABASE_URL: postgresql://root:password@myhost:5432/splitmate?schema=public&connect_timeout=60 ports: - 3000:3000 volumes: postgres-data:
简化版替代方案(无需脚本)
如果不想用初始化脚本,可直接在Dockerfile的CMD中串联命令:
CMD ["sh", "-c", "until pg_isready -h myhost -p 5432 -U root; do sleep 2; done; npx prisma db push; node server.js"]
注意:同样需要在deploy阶段安装postgresql-client,并保持docker-compose.yml的健康检查配置。
内容的提问来源于stack exchange,提问作者JohnnyTheTank
相关产品推荐
相关产品推荐

