Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql Docker中的NestJS可以';不要在另一个Docker容器中的Postgres上迁移Prisma_Postgresql_Docker_Docker Compose_Nestjs_Prisma - Fatal编程技术网

Postgresql Docker中的NestJS可以';不要在另一个Docker容器中的Postgres上迁移Prisma

Postgresql Docker中的NestJS可以';不要在另一个Docker容器中的Postgres上迁移Prisma,postgresql,docker,docker-compose,nestjs,prisma,Postgresql,Docker,Docker Compose,Nestjs,Prisma,我在为NestJS应用程序创建Docker映像时遇到了一个问题,该应用程序通过Prisma与已经在另一个容器中运行的Postgress数据库通信。 问题是在Docker构建的“prisma生成”阶段无法访问数据库 这是简短的版本。:-) docker compose数据库 首先,docker compose在“docker compose up-d”之后运行良好的数据库: version: '3.9' services: db: image: postgres:latest

我在为NestJS应用程序创建Docker映像时遇到了一个问题,该应用程序通过Prisma与已经在另一个容器中运行的Postgress数据库通信。 问题是在Docker构建的“prisma生成”阶段无法访问数据库

这是简短的版本。:-)

docker compose数据库 首先,docker compose在“docker compose up-d”之后运行良好的数据库:

version: '3.9'

services:
  db:
    image: postgres:latest
    restart: "no"
    container_name: hwpostgres
    volumes:
      - ./database:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: root
      POSTGRES_USER: root
      POSTGRES_DB: taskDb

networks:
  default:
    external:
      name: my-network

docker由API组成 另一个docker compose文件正在构建NestJS API应用程序:

ersion: '3.9'

services:
  api:
    build:
      context: ./build
      dockerfile: Dockerfile_api
    image: hwapi
    restart: "no"
    container_name: hwapi
    environment:
      DATABASE_URL: postgresql://root:root@hwpostgres:5432/tasksDb?schema=public
    ports:
      - "8080:3001"
    command: ["node", "dist/main.js"]

networks:
  default:
    external:
      name: cops-net
Dockerfile_api Dockerfile_api如下所示:

FROM node:latest As development
ARG DATABASE_URL=postgresql://root:root@hwpostgres:5432/tasksDb?schema=public
ENV DATABASE_URL $DATABASE_URL

WORKDIR /usr/src/app

COPY . .

RUN npm install -g npm@7.6.3
RUN npm install
RUN npx prisma migrate dev --name init --preview-feature
RUN npm run build
这里显示的Dockerfile_api显然是由多部分组成的Dockerfile的第一个阶段,但是第二部分对这个问题描述并不感兴趣

问题是“npx prisma migrate”命令失败,因为它找不到数据库。 构建过程中该部分的输出:

Step 8/9 : RUN npx prisma migrate dev --name init --preview-feature
 ---> Running in 938d6538806a
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "tasksDb", schema "public" at "hwpostgres:5432"

Error: P1001: Can't reach database server at `hwpostgres`:`5432`

Please make sure your database server is running at `hwpostgres`:`5432`.
所以,它说数据库有问题

交互地做同样的事情 当我将Dockerfile_api更改为以下内容时:

FROM node:latest As development
ARG DATABASE_URL=postgresql://root:root@hwpostgres:5432/tasksDb?schema=public
ENV DATABASE_URL $DATABASE_URL

WORKDIR /usr/src/app

COPY . .

RUN npm install -g npm@7.6.3
RUN npm install
# RUN npx prisma migrate dev --name init --preview-feature
# RUN npm run build
并将docker-compose.yml中此Dockerfile的命令更改为

    command: ["sleep", "3650d"]
然后容器在完成构建后继续运行

然后进入创建的Docker容器(Docker exec-it hwapi/bin/bash), 然后执行“npm prisma migrate”命令,一切正常

其产出如下:

/usr/src/app# echo $DATABASE_URL
postgresql://root:root@hwpostgres:5432/tasksDb?schema=public
/usr/src/app# npx prisma migrate dev --name init --preview-feature
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "tasksDb", schema "public" at "hwpostgres:5432"

Already in sync, no schema change or pending migration was found.
/usr/src/app#
因此,这里看起来它能够找到运行数据库的容器


为什么它在构建阶段找不到数据库,而在同一容器的交互式版本中执行Prisma迁移时它可以找到数据库?

诀窍在于,当您在docker compose设置中运行docker容器时,您可以在与数据库相同的docker网络中运行它

运行
docker build
时,您与数据库不在同一docker网络中,因此数据库找不到它

就个人而言,我建议不要将迁移步骤作为映像构建的一部分来运行,而是将其作为容器启动过程的一部分来运行—可能是在自定义
ENTRYPOINT
脚本中


如果您想将迁移作为映像构建的一部分,可以尝试运行
docker build--network=my network
,其中
my network
是您将正在运行的数据库连接到的网络的名称。

答案也是正确的,我只是想在我的示例中添加它,但有同样的问题,我只需将图像添加到主机网络,方法是将其写入docker-compose.yml文件:

network_mode: "host"

然后,我们可以连接到主机数据库,我们可以完成脚本的其余部分。因此,总而言之,如果您不想将postgres作为单独的映像使用,但在主机linux机器中,那么您可以使用提供的代码。

您是否可以尝试将服务保存在一个单独的组合文件中,如图所示,然后进行检查?实际的问题是,为什么在构建阶段您不在同一个docker网络中?那么这个“docker构建”阶段是什么?显然,这方面存在许多变通办法。就像你建议的那样,把所有东西都放在同一个docker compose设置中(我特别不想要)。我已经尝试在docker构建阶段之外进行数据库迁移。你的入口点建议很好,谢谢。