You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose环境下Knex无法连接PostgreSQL的问题求助

Docker Compose中Knex无法连接PostgreSQL:ECONNREFUSED错误排查与解决

问题描述

我正尝试将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。

具体修复步骤如下:

  1. 修正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'
        }
      }
    };
    
  2. 移除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
    
  3. 验证连接逻辑
    你的start.sh中用psql连接时没有指定端口,默认使用5432,所以能成功连接,这也证明了容器内部PostgreSQL的端口确实是5432,只是Knex的配置端口错了。

做完以上修改后,重新构建并启动容器,Knex应该就能正常连接PostgreSQL并执行迁移了。


内容的提问来源于stack exchange,提问作者boehm_s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:03:52