我在为一个NestJS应用程序创建Docker Image时遇到了一个问题,该应用程序通过Prisma与已经在另一个容器中运行的Postgress数据库进行通信。问题是,在Docker构建的“prisma生成”阶段,is无法访问数据库。
这是一个简短的版本。:-)
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-networkdocker- API的组成
还有另一个构建NestJS应用程序的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-netDockerfile_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并将此Dockerfile的docker-compose.yml中的命令更改为
command: ["sleep", "3650d"]然后容器在完成构建后继续运行。
然后我进入创建的Docker Container (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#因此,这里看起来它能够找到运行数据库的Container。
为什么在构建阶段它找不到数据库,而当我在同一个容器的交互式版本中执行Prisma迁移时,它可以找到数据库?
发布于 2021-03-18 08:14:52
诀窍在于,当您在docker-compose设置中运行docker容器时,您可以在与数据库相同的docker网络中运行它。
当您运行docker build时,您不在与您的数据库相同的docker网络中,因此它无法找到它。
就我个人而言,我建议不要将迁移步骤作为映像构建的一部分运行,而是将其作为容器启动过程的一部分运行--可能是在自定义的ENTRYPOINT脚本中。
如果您希望将迁移作为映像构建的一部分,可以尝试运行docker build --network=my-network,其中my-network是您将正在运行的数据库附加到的网络的名称。
发布于 2021-05-02 23:47:35
答案也是正确的,我只是想补充一下,在我的例子中,有同样的问题,我只是必须将镜像添加到主机网络,通过在docker-compose.yml文件中写入以下代码:
network_mode: "host"然后,我们可以连接到主机数据库,并且可以执行脚本的其余部分。因此,总而言之,如果您不想将postgres用作单独的映像,但是在linux主机上,那么您可以使用提供的代码。
https://stackoverflow.com/questions/66615707
复制相似问题