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

Docker Compose中Node.js无法连接PostgreSQL的问题排查

Node.js无法连接PostgreSQL容器的排查与修复

我尝试用Docker Compose部署Node.js、PostgreSQL和Nginx服务,但Node.js应用抛出连接错误:

2025-04-02 20:07:11 Connection error Error: connect ECONNREFUSED 127.0.0.1:5432
2025-04-02 20:07:11 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)

相关配置文件及代码如下:

docker-compose.yml

services:
  nginx:
    image: nginx:latest
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
    depends_on:
      - node-api

  node-api:
    build: .
    environment:
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_NAME=database
      - DB_USER=postgres
      - DB_PASSWORD=password
    ports:
      - "3000:3000"
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgis/postgis:latest
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: database
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres", "-h", "localhost"]
      interval: 10s
      retries: 5
      start_period: 30s
      timeout: 10s


volumes:
  postgres-data:

Dockerfile

# Use an official Node.js runtime as a parent image
FROM node:18

# Set the working directory
WORKDIR /app

# Copy package.json and install dependencies
COPY package.json package-lock.json ./
RUN npm install

# Copy the rest of the application
COPY . .

# Expose the port the app runs on
EXPOSE 3000

# Start the application
CMD ["node", "api/apis.js"]

api.js

import express from 'express'
import cors from 'cors'
import client from './postgres_connection.js'


const app = express();

app.use(cors());

app.use(express.json());



app.get('/getMarkers', async (req, res) => {
    try {

        const result = await client.query('SELECT * FROM public.topo_markers');
        res.json(result.rows);

    }
    catch (errr) {
        console.error(errr.message);
        res.status(500).send('Internal server error');
    }
});


app.post('/addMarker', async (req, res) => {
    const { title, description, latitude, longitude } = req.body;

    const isBodyEmpty = !title || !description || !latitude || !longitude;

    if (isBodyEmpty) {
        return res.status(400).send('Missing required properties');
    }

    try {
        const query = `
        INSERT INTO public.topo_markers (title, description, geom)
        VALUES ($1, $2, ST_SetSRID(ST_MakePoint($3, $4), 4326)) RETURNING *;
    `;

        const result = await client.query(query, [title, description, longitude, latitude]);

        res.status(201).json(result.rows[0]);

    } catch (errr) {
        console.error(errr.message);
        res.status(500).send('Internal server error');
    }
});

app.listen(3000)

postgres_connection.js

import pg from 'pg';


const client = new pg.Client({
  user: 'postgres',  // Default is usually 'postgres'
  host: 'localhost',           // Use the container's IP if needed
  database: 'test_database',   // Change to your database name
  password: 'password',   // Set this properly
  port: 5432,                  // Default PostgreSQL port
});

client.connect()
  .then(() => console.log('Connected to PostGIS!'))
  .catch(err => console.error('Connection error', err.stack));


export default client;

问题根源与修复步骤

1. 硬编码连接配置未使用环境变量

你的postgres_connection.js直接写死了host: 'localhost'和database: 'test_database',但Docker Compose容器间通信需用服务名(postgres)作为主机名,且你在docker-compose.yml中配置的数据库名是database,与代码中的test_database不一致。

修复postgres_connection.js:

import pg from 'pg';

const client = new pg.Client({
  user: process.env.DB_USER || 'postgres',
  host: process.env.DB_HOST || 'localhost',
  database: process.env.DB_NAME || 'test_database',
  password: process.env.DB_PASSWORD || 'password',
  port: process.env.DB_PORT || 5432,
});

client.connect()
  .then(() => console.log('Connected to PostGIS!'))
  .catch(err => console.error('Connection error', err.stack));

export default client;

2. 容器间通信逻辑验证

Docker Compose会为所有服务创建默认网络,服务名postgres可直接解析为对应容器的IP。只要Node.js服务的环境变量正确注入,就能通过postgres:5432访问数据库。

3. 数据库名称一致性

docker-compose.yml中PostgreSQL的POSTGRES_DB为database,修复后通过环境变量DB_NAME统一配置,避免数据库名称不匹配导致的连接失败。

4. 健康检查有效性

当前PostgreSQL健康检查配置合理,node-api服务的depends_on已设置为等待PostgreSQL服务就绪,确保Node.js启动时数据库已可正常连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:44:54