Docker容器中Keystone6无法连接PostgreSQL:P1001错误求助
问题描述
尝试将Keystone6项目打包为Docker镜像并通过docker-compose部署,连接PostgreSQL数据库。本地直接运行可正常连接数据库,但容器启动后应用报错:
di-wrapp-container | Error: P1001: Can't reach database server at `localhost`:`5432` ... di-wrapp-container exited with code 1
PostgreSQL容器已显示就绪,但应用容器始终无法连接。
问题根源
- 容器内的
localhost指向容器自身,而非PostgreSQL容器。docker-compose中服务间需通过服务名称(即postgres)作为DNS别名通信。 - 应用的
DATABASE_URL硬编码了localhost,且docker-compose的环境变量未正确覆盖该值。 - Dockerfile提前复制了本地
.env文件,导致docker-compose的环境变量无法生效;应用容器的volume配置有误,可能引发文件覆盖问题。 depends_on仅保证PostgreSQL容器先启动,不代表数据库服务已完全就绪。
修复步骤
1. 修正docker-compose配置
修改应用容器的环境变量,替换localhost为PostgreSQL服务名postgres,并直接设置DATABASE_URL确保连接字符串正确;同时调整volume配置避免依赖文件冲突:
version: "3.8" services: postgres: image: postgres:15-alpine container_name: di-wrapp-postgres # 避免和localhost名称冲突 restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=di_wrapp ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data dashboard: image: di-wrapp:1.0 container_name: di-wrapp-container restart: always environment: - NODE_ENV=development - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/di_wrapp tty: true depends_on: - postgres ports: - 8273:9999 command: "npm run dev" volumes: - .:/usr/src/app # 挂载本地代码实现开发热重载(生产环境可移除) - /usr/src/app/node_modules # 避免本地node_modules覆盖容器内依赖 volumes: postgres-data:
2. 优化Dockerfile
移除本地.env的复制操作,让docker-compose环境变量生效;同时调整构建顺序利用Docker缓存:
FROM node:18.13.0-alpine3.16 LABEL Name="di-wrapp" Version="1" ENV NODE_ENV=development WORKDIR /usr/src/app # 先复制依赖文件,缓存安装层 COPY package*.json ./ RUN npm install # 复制项目代码 COPY . . EXPOSE 9999 CMD ["npm", "run", "dev"]
3. 确保应用正确读取环境变量
更新Keystone配置文件,优先读取环境变量中的DATABASE_URL:
import { config } from 'dotenv'; config(); // 确保加载环境变量 export const db: DatabaseConfig<BaseKeystoneTypeInfo> = { provider: "postgresql", url: process.env.DATABASE_URL || "postgresql://postgres:postgres@localhost:5432/di_wrapp", };
4. 添加数据库就绪等待(可选但推荐)
由于depends_on不等待数据库服务就绪,添加等待脚本避免应用提前启动:
- 在Dockerfile中安装PostgreSQL客户端工具:
RUN apk add --no-cache postgresql-client
- 在项目
package.json中添加等待脚本:
{ "scripts": { "wait-for-db": "until pg_isready -h postgres -p 5432 -U postgres; do sleep 2; done", "dev": "npm run wait-for-db && keystone dev" } }
验证步骤
- 重新构建镜像:
docker build -t di-wrapp:1.0 . - 启动容器:
docker-compose up - 查看日志,确认应用成功连接数据库。
内容的提问来源于stack exchange,提问作者Mustafa
相关产品推荐
相关产品推荐

