Spring Boot Docker化失败:无法连接PostgreSQL Docker容器
Spring Boot Docker化后无法连接PostgreSQL的排查与解决
问题概述
项目在本地localhost运行正常,但Docker化后,无论使用PostgreSQL的Docker服务名postgresdb还是localhost作为数据源URL,均无法连接数据库,核心报错为java.net.UnknownHostException: postgresdb。
核心错误分析
从堆栈信息来看,最底层的异常是主机名解析失败,说明Spring容器无法识别postgresdb这个服务名,结合Docker环境,主要原因集中在:网络配置不生效、服务启动时机不匹配、Docker构建/运行方式存在问题、PostgreSQL配置错误。
解决方案
1. 修正Dockerfile构建逻辑
当前Dockerfile直接在容器内执行mvn spring-boot:run,既低效又可能引发网络权限问题,建议构建成独立Jar包后运行:
FROM amazoncorretto:17 WORKDIR /app # 先复制pom.xml缓存依赖,加速构建 COPY pom.xml . RUN mvn dependency:go-offline # 复制源码并构建Jar包 COPY src ./src RUN mvn clean package -DskipTests # 运行Jar包(替换为你的实际Jar包名称) CMD ["java", "-jar", "target/pit-0.0.1-SNAPSHOT.jar"]
2. 修复PostgreSQL数据卷路径+添加健康检查
官方PostgreSQL镜像的默认数据目录是/var/lib/postgresql/data,原配置的/var/lib/postgres路径错误,会导致数据库启动异常;同时添加健康检查,确保PostgreSQL完全就绪后再启动Spring应用:
修改docker-compose.yml中postgresdb服务配置:
postgresdb: image: postgres restart: unless-stopped env_file: ./.env environment: - POSTGRES_USER=$POSTGRESDB_USER - POSTGRES_PASSWORD=$POSTGRESDB_ROOT_PASSWORD - POSTGRES_DB=$POSTGRESDB_DATABASE ports: - $POSTGRESDB_LOCAL_PORT:$POSTGRESDB_DOCKER_PORT volumes: - db:/var/lib/postgresql/data # 修正数据卷路径 networks: - sng-network healthcheck: test: ["CMD-SHELL", "pg_isready -U $POSTGRESDB_USER -d $POSTGRESDB_DATABASE"] interval: 5s timeout: 5s retries: 5
3. 配置Spring应用等待PostgreSQL就绪
在docker-compose.yml的app服务中,修改depends_on配置,确保仅在PostgreSQL健康检查通过后启动:
app: depends_on: postgresdb: condition: service_healthy # 等待PostgreSQL就绪 build: ./ restart: on-failure env_file: ./.env ports: - $SPRING_LOCAL_PORT:$SPRING_DOCKER_PORT environment: SPRING_APPLICATION_JSON: '{ "spring.datasource.url" : "jdbc:postgresql://postgresdb:$POSTGRESDB_DOCKER_PORT/$POSTGRESDB_DATABASE", "spring.datasource.username" : "$POSTGRESDB_USER", "spring.datasource.password" : "$POSTGRESDB_ROOT_PASSWORD", "spring.jpa.properties.hibernate.dialect" : "org.hibernate.dialect.PostgreSQLDialect", "spring.jpa.hibernate.ddl-auto" : "update" }' volumes: - .m2:/root/.m2 stdin_open: true tty: true networks: - sng-network
4. 验证环境变量一致性
确保.env文件中的变量与docker-compose.yml引用一致,示例.env内容:
POSTGRESDB_USER=postgres POSTGRESDB_ROOT_PASSWORD=postgres POSTGRESDB_DATABASE=donations POSTGRESDB_LOCAL_PORT=5432 POSTGRESDB_DOCKER_PORT=5432 SPRING_LOCAL_PORT=8080 SPRING_DOCKER_PORT=8080
验证步骤
- 停止并清理现有容器与数据卷:
docker-compose down -v
- 重新构建并启动服务:
docker-compose up --build
- 查看Spring应用日志,确认连接状态:
docker-compose logs -f app
关键注意事项
- 容器内不能用
localhost连接PostgreSQL,容器的localhost指向自身,必须使用Docker服务名postgresdb。 - Docker构建时优先缓存依赖,避免每次构建都重新下载Maven包。
- PostgreSQL数据卷路径错误会导致数据库启动失败,间接引发Spring连接异常。
内容的提问来源于stack exchange,提问作者Harshit
相关产品推荐
相关产品推荐

