Docker环境下Prisma无法连接PostgreSQL数据库求助
Docker部署Prisma+PostgreSQL数据库连接失败问题
问题经过
- 初始配置docker-compose.yml和Dockerfile后,启动时出现
Can't reach database server at localhost:5432错误;单独启动数据库容器后,本地执行yarn start可正常连接。 - 按建议修改配置:将数据库地址从
localhost改为db,使用wait-for-it脚本等待数据库启动,将迁移命令移至compose.yml中,但仍出现Can't reach database server at db:5432错误。
各阶段配置文件
初始docker-compose.yml
version: '3.8' services: pg-prisma-rest: image: postgres:13 restart: always environment: - POSTGRES_USER=prisma_pg - POSTGRES_PASSWORD=benchmark volumes: - postgres:/var/lib/postgresql/data ports: - '5432:5432' app: stdin_open: true restart: always build: context: . dockerfile: Dockerfile container_name: app depends_on: - pg-prisma-rest ports: - "3050:3000" volumes: postgres:
初始Dockerfile
FROM node:alpine COPY package*.json ./ COPY . . RUN yarn RUN npx prisma migrate dev --name "init" RUN npx prisma generate
修改后的docker-compose.yml
version: '3.8' services: db: image: postgres:13 restart: always volumes: - postgres:/var/lib/postgresql/data env_file: - .env ports: - '5432:5432' app: build: . depends_on: - db volumes: - .:/app ports: - '3000:3000' entrypoint: ["wait-for-it.sh", "db:5432", "--"] command: ["yarn", "start:migrate"] volumes: postgres:
修改后的Dockerfile
FROM node:lts-bookworm-slim COPY dataset ./dataset COPY tsconfig.json ./ WORKDIR /src/app COPY package*.json yarn.lock ./ COPY prisma ./prisma/ RUN yarn COPY . . COPY wait-for-it.sh /usr/local/bin/wait-for-it.sh RUN chmod +x /usr/local/bin/wait-for-it.sh EXPOSE 3000
package.json脚本
{ ... "scripts": { "start": "NODE_OPTIONS='--max-old-space-size=8192' ts-node -r dotenv/config index.ts", "start:prod": "node dist/main", "build": "rimraf ./build && tsc", "start:migrate": "prisma migrate deploy && yarn start", "dev": "ts-node-dev --respawn --transpile-only src/server.ts", "studio": "prisma studio" } }
最终错误信息
wait-for-it.sh: waiting 15 seconds for db:5433 prisma-express-rest-db-1 | yarn run v1.22.19 prisma-express-rest-db-1 | $ prisma migrate deploy && yarn start prisma-express-rest-db-1 | Environment variables loaded from .env prisma-express-rest-db-1 | Prisma schema loaded from prisma/schema.prisma prisma-express-rest-db-1 | Datasource "db": PostgreSQL database "prisma", schema "list" at "db:5432" prisma-express-rest-db-1 | prisma-express-rest-db-1 | Error: P1001: Can't reach database server at `db`:`5432`
排查与解决方法
1. 紧急修复:wait-for-it脚本端口参数错误
从错误日志可见,wait-for-it脚本正在等待db:5433,但数据库容器端口是5432,属于明显的参数笔误。检查docker-compose.yml中app服务的entrypoint配置,确认端口为db:5432后重新部署。
2. 解决PostgreSQL就绪检测不彻底问题
wait-for-it仅检测端口是否开放,但PostgreSQL开放端口后还需10-30秒初始化数据库,此时连接仍会失败,可换用更可靠的检测方式:
方法一:延长wait-for-it超时时间
修改entrypoint,将超时时间增加至30秒:
entrypoint: ["wait-for-it.sh", "db:5432", "-t", "30", "--"]
方法二:用pg_isready检测服务真正就绪
在Dockerfile中安装postgresql-client:
RUN apt-get update && apt-get install -y postgresql-client && rm -rf /var/lib/apt/lists/*
然后修改app服务的entrypoint:
entrypoint: ["sh", "-c", "until pg_isready -h db -p 5432 -U ${POSTGRES_USER}; do sleep 2; done; yarn start:migrate"]
(需确保.env文件中定义了POSTGRES_USER)
3. 检查.env文件数据库配置
确认.env中的DATABASE_URL格式正确,主机名必须为compose中的服务名db:
DATABASE_URL="postgresql://POSTGRES_USER:POSTGRES_PASSWORD@db:5432/POSTGRES_DB?schema=public"
- 替换
POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB为实际值,需与db服务的环境变量一致(db服务使用env_file,因此.env需包含这三个变量) - 禁止使用
localhost作为主机名,Docker容器间通信需用服务名
4. 修复容器工作目录与挂载路径不匹配问题
修改后的Dockerfile设置了WORKDIR /src/app,但compose中的volumes是.:/app,导致本地代码挂载到/app目录,而容器工作目录为/src/app,执行命令时会找不到文件,二选一修正:
- 将Dockerfile中的
WORKDIR /src/app改为WORKDIR /app - 或将compose中的volumes改为
.:/src/app
5. 确认Docker网络配置
默认情况下,docker-compose会为所有服务创建共享网络,确保app和db服务处于同一网络。若自定义了网络,需确保两个服务都加入该网络:
networks: app-network: driver: bridge services: db: ... networks: - app-network app: ... networks: - app-network
内容的提问来源于stack exchange,提问作者Amir Meyari
相关产品推荐
相关产品推荐

