如何在Docker中使用Prisma生成数据库表

alw*_*ing 5 postgresql node.js docker docker-compose prisma

目标

我正在尝试制作一个最小的Express应用程序。它有一个端点/users,可以获取Postgres 数据库中的所有用户,也可以发布新用户。我正在尝试使用Prisma作为 ORM 并使用docker-compose运行所有内容。

我正在尝试专门构建这个最小的示例,目的是了解如何将 Prisma 与 docker-compose 一起使用。

问题

最终我希望用户能够简单地运行docker-compose up并让一切正常工作。这意味着我假设不存在现有数据库卷,因此,在构建映像时,Docker 需要

  1. 在 Postgres 容器中创建一个users数据库(?我不确定这是否是按照连接 URL 中定义的默认创建的)

  2. 在该数据库中创建一个users,我希望使用该表npx prisma db pushschema.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"
  }
}
Run Code Online (Sandbox Code Playgroud)

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"]
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

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"]
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

.env

DATABASE_URL="postgresql://postgres:postgres@db:5432/users"
Run Code Online (Sandbox Code Playgroud)

index.js

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
Run Code Online (Sandbox Code Playgroud)