如何解决Docker 中的 NestJS 无法在另一个 Docker 容器中的 Postgres 上执行 Prisma Migrate
我在为 NestJS 应用程序创建 Docker 映像时遇到问题,该应用程序通过 Prisma 与已在另一个容器中运行的 Postgress 数据库通信。 问题是在 Docker Build 的“prisma generate”阶段无法访问数据库。
那是简短的版本。 :-)
docker-compose 数据库
首先,在'docker-compose up -d'之后运行良好的数据库的docker-compose:
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
API 的 docker-compose
还有另一个构建 NestJS API 应用程序的 docker-compose 文件:
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 的第一阶段,但第二部分对于这个问题描述并不有趣。
问题是'npxprisma 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
并将此 Dockerfile 的 docker-compose.yml 中的命令更改为
command: ["sleep","3650d"]
然后容器在完成构建后继续运行。
然后我进入创建的 Docker 容器(docker exec -it hwapi /bin/bash), 然后执行'npmprisma 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#
所以,这里看起来可以找到运行数据库的容器。
为什么在Build阶段找不到数据库,而我在同一个Container的交互版本中进行Prisma Migrate时却可以找到数据库?
解决方法
诀窍是,当您在 docker-compose 设置中运行 docker 容器时,您会在与数据库相同的 docker 网络中运行它。
当您运行 docker build
时,您与您的数据库不在同一个 docker 网络中,因此它找不到它。
就我个人而言,我建议不要将迁移步骤作为映像构建的一部分运行,而是将其作为容器启动过程的一部分运行 - 可能在自定义 ENTRYPOINT
脚本中。
如果您希望将迁移作为映像构建的一部分,您可以尝试运行 docker build --network=my-network
,其中 my-network
是您将运行的数据库附加到的网络的名称。>
答案也是正确的,我只是想在我的情况下添加它,遇到同样的问题,我只需要将图像添加到主机网络,通过在 docker-compose.yml 文件中写入:>
network_mode: "host"
然后,我们可以连接到主机数据库,我们可以完成脚本的其余部分。所以,总而言之,如果您不想将 postgres 用作单独的映像,而是在主机 linux 机器中,那么您可以使用提供的代码。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。