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

为Express API在Docker容器部署PostgreSQL遇主机名解析错误

问题解决:Docker部署Express+PostgreSQL时主机名解析失败

核心问题分析

  1. 构建阶段无法访问数据库容器:Dockerfile里的RUN psql...命令是在镜像构建阶段执行的,此时数据库容器还没启动,也未加入共享网络,自然无法解析db这个主机名。
  2. 数据库配置重复冲突:docker-compose已通过环境变量指定了POSTGRES_DB、POSTGRES_USER,但init.sql又重复创建同名数据库和用户,会触发报错。
  3. 连接地址错误:db.js里的数据库主机写的是postgres,但docker-compose中数据库服务的名称是db,两者不匹配导致无法解析。

分步修正方案

1. 移除Dockerfile中构建阶段执行SQL的命令

删除Dockerfile中以下这段代码:

RUN apt-get update -y && apt-get install -y postgresql-client && \
    /bin/bash -c "psql -h db -U postgres -f setup/init.sql"

镜像构建阶段根本无法连接到未启动的数据库容器,SQL初始化逻辑需要调整到容器启动阶段执行。

2. 改用Postgres自动初始化脚本机制

Postgres官方镜像会自动执行/docker-entrypoint-initdb.d/目录下的SQL脚本,修改docker-compose.yaml,将init.sql挂载到该目录:

services:
  db:
    image: postgres:latest
    restart: always
    environment: 
      POSTGRES_USER: emirb
      POSTGRES_PASSWORD: emir123
      POSTGRES_DB: node
    ports:
      - "5432:5432"
    networks:
      - node_network
    container_name: db
    volumes:
      - ./setup/init.sql:/docker-entrypoint-initdb.d/init.sql  # 新增挂载配置

同时修改init.sql,删除重复创建数据库的语句(docker-compose已经指定了初始数据库):

/* Database table creation will be done in db.js */

-- Create user
CREATE USER db_admin WITH SUPERUSER PASSWORD 'admin123';

-- Grant database privileges
GRANT ALL PRIVILEGES ON DATABASE node TO db_admin;

3. 修正数据库连接地址

修改db.js中的主机配置,将postgres改为db(对应docker-compose中的服务名):

const connectionOptions = {
    host: 'db',  // 修正为docker-compose中的数据库服务名
    port: 5432,
    database: 'node',
    user: 'emirb',
    password: 'emir123',
};

4. 优化容器启动顺序(可选但推荐)

depends_on仅保证数据库容器先启动,但不保证Postgres服务就绪。添加健康检查,确保数据库可用后再启动API服务:

services:
  db:
    image: postgres:latest
    restart: always
    environment: 
      POSTGRES_USER: emirb
      POSTGRES_PASSWORD: emir123
      POSTGRES_DB: node
    ports:
      - "5432:5432"
    networks:
      - node_network
    container_name: db
    volumes:
      - ./setup/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:  # 新增健康检查
      test: ["CMD-SHELL", "pg_isready -U emirb -d node"]
      interval: 5s
      timeout: 5s
      retries: 5

  api:
    build: .
    ports: 
      - "3000:3000"
    depends_on:
      db:
        condition: service_healthy  # 等待数据库健康检查通过再启动
    networks:
      - node_network
    container_name: api

5. 重新构建启动容器

执行以下命令清理旧资源并重新部署:

docker compose down -v
docker compose build --no-cache
docker compose up -d

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:34:58