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

Docker环境下Node.js连接PostgreSQL遇ECONNREFUSED错误的解决求助

解决Docker环境下Node.js连接PostgreSQL的ECONNREFUSED错误

问题背景

我使用Node.js开发API服务,数据存储于PostgreSQL数据库,但在Docker环境中连接PostgreSQL时反复出现连接拒绝错误,仅能通过删除并重启容器临时解决,需要彻底修复。

错误信息

(node:25) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 10.106.238.66:5432
    at /app/node_modules/pg-pool/index.js:45:11
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:25) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:25) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Error: connect ECONNREFUSED 10.106.238.66:5432
    at /app/node_modules/pg-pool/index.js:45:11
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '10.106.238.66',
  port: 5432
}

Node.js连接代码

const { Pool } = require("pg");
const pgClient = new Pool({
  user: keys.pgUser,
  host: keys.pgHost,
  database: keys.pgDatabase,
  password: keys.pgPassword,
  port: keys.pgPort,
  // user: "postgres",
  // host: "postgres",
  // database: "postgres",
  // password: "password",
  // port: 5432,
});

pgClient.connect();

pgClient.on("connect", () => {
  console.log("db connected");
});

Docker Compose配置

version: "3"

services:
  postgres:
    image: "postgres:latest"
    environment:
      - POSTGRES_PASSWORD=password
  redis:
    image: "redis:latest"
  nginx:
    depends_on:
      - api
      - client
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - "3050:80"
  api: # Changed from server to api, as nginx has server as reserved keyword
    build:
      dockerfile: Dockerfile.dev
      context: ./server # The path is specified in the context while only the name is specified in the dockerfile
    volumes:
      - /app/node_modules
      - ./server:/app
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379 #From docs
      - PG_USER=postgres
      - PG_HOST=postgres
      - PG_DATABASE=postgres
      - PG_PASSWORD=password
      - PG_PORT=5432 #From docs
    restart: always
  client:
    build:
      dockerfile: Dockerfile.dev
      context: ./client #The path from where to pick the dockerfile
    volumes:
      - /app/node_modules
      - ./client:/app
    environment:
      - WATCHPACK_POLLING=true
  worker:
    build:
      dockerfile: Dockerfile.dev
      context: ./worker
    volumes:
      - /app/node_modules
      - ./worker:/app
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379

彻底解决方案

1. 确保PostgreSQL服务就绪后再启动API

Docker Compose的depends_on仅保证容器启动顺序,不等待服务就绪。给PostgreSQL添加健康检查,并让API服务等待其健康状态:

修改docker-compose.yml中的postgres服务:

postgres:
  image: "postgres:latest"
  environment:
    - POSTGRES_PASSWORD=password
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U postgres"]
    interval: 5s
    timeout: 5s
    retries: 5

给api服务添加依赖条件:

api:
  # ...其他配置
  depends_on:
    postgres:
      condition: service_healthy

2. 验证环境变量加载正确性

在Node.js代码中添加日志,确认pgHost是postgres而不是错误的IP:

console.log('PostgreSQL Host:', keys.pgHost); // 检查输出是否为"postgres"

如果输出是10.106.238.66,说明环境变量未正确加载,检查:

  • 容器启动时是否有环境变量覆盖
  • keys模块是否正确读取环境变量(比如是否用process.env.PG_HOST)

3. 添加连接重试与错误处理

给pg-pool配置重试策略,并处理连接错误,避免未捕获的Promise拒绝:

const pgClient = new Pool({
  user: keys.pgUser,
  host: keys.pgHost,
  database: keys.pgDatabase,
  password: keys.pgPassword,
  port: keys.pgPort,
  retryDelayMillis: 1000, // 每次重试间隔1秒
  numberOfRetries: 5 // 最多重试5次
});

// 显式处理连接结果
pgClient.connect()
  .then(() => console.log("db connected"))
  .catch(err => console.error("Failed to connect to database:", err));

4. 检查PostgreSQL监听地址

进入PostgreSQL容器,确认服务监听所有网络接口:

docker exec -it <postgres-container-id> netstat -tulpn | grep 5432

确保输出包含0.0.0.0:5432,而非仅127.0.0.1:5432。

5. 确认Docker网络一致性

确保所有服务在同一个Docker网络中(docker-compose默认会创建专属网络),不要手动为服务指定独立网络,避免网络隔离。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:55:23