为Express API在Docker容器部署PostgreSQL遇主机名解析错误
问题解决:Docker部署Express+PostgreSQL时主机名解析失败
核心问题分析
- 构建阶段无法访问数据库容器:Dockerfile里的
RUN psql...命令是在镜像构建阶段执行的,此时数据库容器还没启动,也未加入共享网络,自然无法解析db这个主机名。 - 数据库配置重复冲突:docker-compose已通过环境变量指定了
POSTGRES_DB、POSTGRES_USER,但init.sql又重复创建同名数据库和用户,会触发报错。 - 连接地址错误:
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
相关产品推荐
相关产品推荐

