我正在尝试制作一个最小的 Express 应用程序。它有一个端点
/users
,可以获取 Postgres 数据库中的所有用户,或者发布新用户。我正在尝试使用 Prisma 作为 ORM 并使用 docker-compose 运行所有内容。
我正在尝试专门构建这个最小的示例,目的是了解如何将 Prisma 与 docker-compose 一起使用。
最终我希望用户能够简单地运行
docker-compose up
并让一切正常工作。这意味着我假设不存在现有的数据库卷,因此,在构建映像时,Docker 需要
在 Postgres 容器中创建一个
users
数据库(?我不确定这是否是按照连接 URL 中定义的默认创建的)
在该数据库中创建一个
users
表,我希望使用npx prisma db push
来执行此操作,以便使用schema.prisma
文件
我想知道执行此操作的“正确”方法是什么? 除了基本示例之外,我对 Prisma 和 Docker 还很陌生,因此非常感谢任何见解或建议!
此外,了解在哪里/如何注入
DATABASE_URL
环境变量会很棒。看起来 Prisma 依赖于 .env
文件,但是这是否可以像我所做的那样等效地注入到 docker-compose.yml
中?
我已在下面包含所有相关代码,再次感谢您!
package.json
{
"name": "express_prisma_postgres_compose",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@prisma/client": "^4.12.0",
"body-parser": "^1.20.2",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"pg": "^8.10.0",
"prisma": "^4.12.0"
}
}
Dockerfile
FROM node:lts-alpine
WORKDIR /usr/app
COPY package*.json ./
# use ci instead?
RUN npm install
# Add prisma schema
COPY ./prisma/schema.prisma ./prisma/schema.prisma
# NOTE: Have to copy .env file so that prisma can use it?
# COPY .env ./
# Generate Prisma client
RUN npx prisma generate
# Push changes to DB
RUN npx prisma db push
# Run separately bc different layer. Makes rebuilding image faster.
COPY . .
CMD ["node", "index.js"]
docker-compose.yml
version: '3.8'
services:
db:
image: postgres:14.1-alpine
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRED_DB=users
# We don't have to expose this port because the containers communicate inside the docker network
#ports:
# - '5432:5432'
volumes:
- db:/var/lib/postgresql/data
server:
build:
# Build image from the specified dockerfile in the specified folder.
context: ./
dockerfile: Dockerfile
restart: always
ports:
- '3000:3000'
depends_on:
- db
environment:
#env_file: .env
- DATABASE_URL="postgresql://postgres:postgres@db:5432/users"
volumes:
db:
driver: local
schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model users {
id Int @id @default(autoincrement())
username String? @db.VarChar(50)
}
.env
DATABASE_URL="postgresql://postgres:postgres@db:5432/users"
index.js
const express = require('express');
const bodyParser = require('body-parser');
const { PrismaClient } = require('@prisma/client');
const app = express();
app.use(bodyParser.json());
// Create a new Prisma client instance
const prisma = new PrismaClient();
// Endpoint for retrieving all users from the database
app.get('/users', async (req, res) => {
try {
const users = await prisma.users.findMany();
res.status(200).json(users);
} catch (error) {
console.error(error);
res.status(500).send('Internal server error');
}
});
// Endpoint for adding a new user to the database
app.post('/users', async (req, res) => {
try {
const newUser = req.body;
const { username } = newUser;
const user = await prisma.users.create({
data: {
username,
},
});
res.status(201).json(user);
} catch (error) {
console.error(error);
res.status(500).send('Internal server error');
}
});
// Start the server on port 3000
app.listen(3000, () => {
console.log('Server started on port 3000');
});
在您的服务器应用程序中
Dockerfile
,您可以运行自定义脚本,而不是运行CMD ["node" "index.js"]
:
CMD ["yarn", "start"]
在您的服务器应用程序中
package.json
您可以创建这样的脚本:
"scripts": {
"start": "yarn db:sync && node index.js",
"db:sync": "prisma db push"
}
将
yarn
替换为您最喜欢的工具(例如 npm)。
至于环境变量,看来你已经弄清楚了,你可以通过 docker-compose yaml 注入它们,而不是使用
.env
文件。
这对我有用,尽管我仅将其用于本地开发或演示目的。