Ber*_*rtC 5 postgresql docker docker-compose nestjs prisma
我在为 NestJS 应用程序创建 Docker 映像时遇到问题,该应用程序通过 Prisma 与已在另一个容器中运行的 Postgress 数据库进行通信。问题是在 Docker 构建的“prisma 生成”阶段无法访问数据库。
这是简短的版本。:-)
首先,数据库的 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
Run Code Online (Sandbox Code Playgroud)
还有另一个构建 NestJS API 应用程序的 docker-compose 文件:
version: '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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这里显示的 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`.
Run Code Online (Sandbox Code Playgroud)
所以,它说数据库有问题
当我将 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
Run Code Online (Sandbox Code Playgroud)
并将该 Dockerfile 的 docker-compose.yml 中的命令更改为
command: ["sleep", "3650d"]
Run Code Online (Sandbox Code Playgroud)
然后容器在构建完成后继续运行。
然后我进入创建的 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#
Run Code Online (Sandbox Code Playgroud)
所以,在这里看起来它能够找到运行数据库的容器。
为什么在构建阶段找不到数据库,而在同一个容器的交互版本中进行 Prisma Migrate 时却可以找到数据库?
诀窍在于,当您在 docker-compose 设置中运行 docker 容器时,您将在与数据库相同的 docker 网络中运行它。
当您运行时docker build,您与数据库不在同一个 docker 网络内,因此它找不到它。
就个人而言,我建议不要将迁移步骤作为映像构建的一部分运行,而是将其作为容器启动过程的一部分运行 - 可能在自定义脚本中ENTRYPOINT。
如果您想将迁移保留为映像构建的一部分,您可以尝试运行docker build --network=my-network,其中my-network是您将运行数据库附加到的网络的名称。
| 归档时间: |
|
| 查看次数: |
6428 次 |
| 最近记录: |