如何通过Docker Compose使用Prisma生成Postgres数据库表?
极简Express+Prisma+Docker-Compose应用配置指南
需求概述
构建一个支持/users端点的极简Express应用:
- GET请求获取Postgres中所有用户
- POST请求新增用户
- 用Prisma作为ORM
- 仅需执行
docker-compose up即可启动所有服务,自动完成:- 创建Postgres的
users数据库 - 基于
schema.prisma自动创建users表
- 创建Postgres的
- 明确Prisma与Docker-Compose的环境变量注入方式
关键问题解决方案
1. 自动创建Postgres数据库
Postgres容器默认不会自动创建数据库,需在docker-compose.yml的Postgres服务中配置POSTGRES_DB环境变量,容器启动时会自动生成指定名称的数据库:
# docker-compose.yml 中postgres服务部分 environment: POSTGRES_USER: admin POSTGRES_PASSWORD: password POSTGRES_DB: users # 自动创建users数据库
2. 自动同步Prisma表结构
要在服务启动时自动执行prisma db push,需修改package.json的启动脚本,确保先同步schema再启动Express:
// package.json "scripts": { "start": "npx prisma db push && node index.js" }
同时必须确保Postgres数据库就绪后再执行该命令,否则会出现连接失败。解决方法是给Postgres服务添加健康检查,并让API服务依赖其健康状态:
# docker-compose.yml 中postgres服务部分 healthcheck: test: ["CMD-SHELL", "pg_isready -U admin -d users"] interval: 5s timeout: 5s retries: 5 # api服务部分 depends_on: postgres: condition: service_healthy
3. DATABASE_URL环境变量注入
Prisma支持直接读取系统环境变量,无需依赖.env文件。可直接在docker-compose.yml的API服务中配置:
# docker-compose.yml 中api服务部分 environment: DATABASE_URL: "postgresql://admin:password@postgres:5432/users?schema=public"
这里的postgres是docker-compose中Postgres服务的名称,Docker内部DNS会自动解析到对应容器的IP。
完整配置文件示例
package.json
{ "name": "express-prisma-docker", "version": "1.0.0", "main": "index.js", "scripts": { "start": "npx prisma db push && node index.js", "dev": "nodemon index.js" }, "dependencies": { "@prisma/client": "^5.0.0", "express": "^4.18.2" }, "devDependencies": { "prisma": "^5.0.0", "nodemon": "^3.0.1" } }
Dockerfile
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["npm", "start"]
docker-compose.yml
version: '3.8' services: postgres: image: postgres:15-alpine environment: POSTGRES_USER: admin POSTGRES_PASSWORD: password POSTGRES_DB: users volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U admin -d users"] interval: 5s timeout: 5s retries: 5 api: build: . ports: - "3000:3000" environment: DATABASE_URL: "postgresql://admin:password@postgres:5432/users?schema=public" depends_on: postgres: condition: service_healthy volumes: - .:/app - /app/node_modules volumes: postgres_data:
schema.prisma
generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) name String email String @unique }
index.js
const express = require('express'); const { PrismaClient } = require('@prisma/client'); const app = express(); const prisma = new PrismaClient(); // 解析JSON请求体 app.use(express.json()); // 获取所有用户 app.get('/users', async (req, res) => { const users = await prisma.user.findMany(); res.json(users); }); // 新增用户 app.post('/users', async (req, res) => { const { name, email } = req.body; try { const user = await prisma.user.create({ data: { name, email } }); res.status(201).json(user); } catch (error) { res.status(400).json({ error: error.message }); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
内容的提问来源于stack exchange,提问作者always_learning
相关产品推荐
相关产品推荐

