Docker Compose环境下Knex无法连接PostgreSQL的问题求助
问题描述
我正尝试将NodeJS/PostgreSQL应用容器化,使用Docker Compose部署,但运行knex迁移时遇到如下错误:
Error: connect ECONNREFUSED 172.18.0.2:15432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1161:14)
我能通过CLI连接PostgreSQL,但knex无法连接,刚接触Docker,怀疑存在配置错误。
以下是我的配置文件:
docker-compose.yml
version: "3" services: app: build: . depends_on: - db links: - db ports: - "3000:3000" environment: POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres POSTGRES_DB: users-microservice DB_HOST: db db: image: postgres:10.4-alpine expose: - "5432" ports: - "15432:5432" environment: POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres POSTGRES_DB: users-microservice
app服务的Dockerfile
FROM node:10.1-alpine EXPOSE 3000 9229 15432 COPY . /home/app WORKDIR /home/app RUN npm install RUN npm install -g knex CMD ./scripts/start.sh
start.sh中的等待逻辑(可正常执行)
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$DB_HOST" -U "$POSTGRES_USER" -c '\d'; do >&2 echo "Postgres is unavailable - sleeping" sleep 1 done >&2 echo "Postgres is up - executing command"
问题原因与解决方案
这个错误的核心原因是:你的Knex配置中错误使用了宿主机映射的PostgreSQL端口15432,而不是容器内部的PostgreSQL端口5432。
在Docker Compose的内部网络中,服务之间通信使用的是容器本身暴露的端口(也就是db服务里的5432),而15432是映射给宿主机外部访问用的端口,容器内部的app服务不能用这个端口连接db。
具体修复步骤如下:
修正Knex配置文件(比如
knexfile.js)
确保你的Knex连接配置中,端口设置为5432,而不是15432。示例配置如下:module.exports = { development: { client: 'postgresql', connection: { host: process.env.DB_HOST, // 对应docker-compose里的DB_HOST: db port: 5432, // 容器内部的PostgreSQL端口,不是宿主机的15432 user: process.env.POSTGRES_USER, password: process.env.POSTGRES_PASSWORD, database: process.env.POSTGRES_DB }, migrations: { directory: './migrations' } } };移除Dockerfile中不必要的端口暴露
你的Dockerfile里EXPOSE 3000 9229 15432,其中15432是db服务的端口,app服务根本不需要暴露它,修改为:FROM node:10.1-alpine EXPOSE 3000 9229 COPY . /home/app WORKDIR /home/app RUN npm install RUN npm install -g knex CMD ./scripts/start.sh验证连接逻辑
你的start.sh中用psql连接时没有指定端口,默认使用5432,所以能成功连接,这也证明了容器内部PostgreSQL的端口确实是5432,只是Knex的配置端口错了。
做完以上修改后,重新构建并启动容器,Knex应该就能正常连接PostgreSQL并执行迁移了。
内容的提问来源于stack exchange,提问作者boehm_s

