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

Docker部署Node.js+Spring应用:PostgreSQL未知主机错误求助

问题分析与解决建议

核心问题

你遇到的「Unknown host database」根本原因是:后端Docker镜像构建阶段(执行mvn package时),容器还未加入Docker Compose的自定义网络,无法解析database这个服务名。不管用wait-for-it.sh还是其他等待脚本,在构建阶段都没用——因为构建阶段和Compose运行时的网络环境完全隔离。

解决方案步骤

1. 重构后端Dockerfile,采用多阶段构建

把代码编译打包和应用运行分离,构建阶段只做编译,不依赖数据库;运行阶段才进入Compose网络,此时能正常访问数据库。

示例Dockerfile(放在后端根目录):

# 第一阶段:编译打包(仅用Maven环境,不涉及应用运行)
FROM maven:3.8.6-openjdk-17 AS builder
WORKDIR /app
# 先复制pom.xml下载依赖(利用Docker缓存,避免每次改代码都重下依赖)
COPY pom.xml .
RUN mvn dependency:go-offline
# 再复制源码编译打包,跳过测试(避免测试阶段连接数据库)
COPY src ./src
RUN mvn clean package -DskipTests

# 第二阶段:运行应用(轻量JDK环境)
FROM openjdk:17-jdk-slim
WORKDIR /app
# 从构建阶段复制打好的jar包
COPY --from=builder /app/target/*.jar app.jar
# 启动命令
CMD ["java", "-jar", "app.jar"]

2. 优化Docker Compose的依赖等待逻辑

你的Compose已经配置了数据库健康检查,现在需要让后端容器等待数据库健康检查通过后再启动,避免运行时数据库还未就绪。修改backend服务的depends_on:

backend:
  links:
    - "database"
  depends_on:
    database:
      condition: service_healthy  # 仅当数据库健康检查通过才启动
  build: ./
  ports:
    - '8000:8000'
  restart: always
  environment:
    - 'SPRING_DATASOURCE_URL=jdbc:postgresql://database:5432/userdb'
    - 'SPRING_DATASOURCE_USERNAME=user'
    - 'SPRING_DATASOURCE_PASSWORD=user'

3. 修正数据库健康检查命令

当前健康检查用pg_isready -U postgres,但你的数据库用户是user,可能导致健康检查通过但实际业务用户无法连接。建议修改为:

database:
  # ...其他配置
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U user -d userdb"]
    interval: 10s
    timeout: 5s
    retries: 5

额外注意事项

  • 不要在镜像构建阶段执行需要连接外部服务(比如数据库)的操作,构建应该是离线可重复的,只依赖本地代码和Maven仓库。
  • pom.xml里的dataSource.url会被Compose的环境变量覆盖,无需修改,保持即可。
  • 如果必须在构建阶段运行测试,可考虑使用Testcontainers(在测试代码中临时启动Postgres容器),但对新手来说,先跳过测试能快速解决当前问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:22:53