Docker Compose启动Java应用时无法识别PostgreSQL主机问题求助
Spring Boot + Docker Compose 无法连接PostgreSQL:UnknownHostException 问题解决
问题场景
周末开发基于Spring Boot的Java项目,使用Docker Compose部署PostgreSQL和应用,但执行docker-compose up后,应用抛出java.net.UnknownHostException: postgres,无法连接数据库。单独启动PostgreSQL容器再启动应用仍报错,但本地IDE运行时将数据库主机改为localhost可正常连接。
配置信息
Docker Compose 配置 (docker-compose.yml)
version: '3.8' services: postgres: image: postgres:14 container_name: postgres environment: POSTGRES_DB: database POSTGRES_USER: root POSTGRES_PASSWORD: root ports: - "5432:5432" app: container_name: app build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: - postgres
Spring Boot 配置 (application.properties)
spring.datasource.url=jdbc:postgresql://postgres:5432/database spring.datasource.username=root spring.datasource.password=root spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
关键错误日志
Caused by: java.net.UnknownHostException: postgres at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:331) at java.base/java.net.Socket.connect(Socket.java:630) ...
解决方案
1. 显式定义Docker网络
默认Docker Compose会创建默认网络,但显式定义网络可确保服务处于同一网络环境,避免DNS解析问题:
修改docker-compose.yml,添加网络配置:
version: '3.8' services: postgres: image: postgres:14 container_name: postgres environment: POSTGRES_DB: database POSTGRES_USER: root POSTGRES_PASSWORD: root ports: - "5432:5432" networks: - app-network app: container_name: app build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: - postgres networks: - app-network networks: app-network: driver: bridge
2. 等待数据库服务就绪
depends_on仅保证容器启动顺序,不确保数据库服务已就绪。添加健康检查让应用等待数据库可用:
修改docker-compose.yml中postgres服务,添加健康检查:
postgres: # 保留原有配置 healthcheck: test: ["CMD-SHELL", "pg_isready -U root -d database"] interval: 5s timeout: 5s retries: 5
同时更新app服务的depends_on:
app: # 保留原有配置 depends_on: postgres: condition: service_healthy
3. 验证容器网络连通性
如果以上方案无效,进入app容器测试DNS解析:
docker exec -it app ping postgres
若ping不通,尝试重启Docker服务,或检查容器是否加入同一网络。
4. 使用环境变量动态配置数据库地址
避免硬编码,通过环境变量适配不同环境:
修改application.properties:
spring.datasource.url=jdbc:postgresql://${DB_HOST:postgres}:5432/${DB_NAME:database} spring.datasource.username=${DB_USER:root} spring.datasource.password=${DB_PASSWORD:root}
在docker-compose.yml的app服务中可添加环境变量(可选,已设置默认值):
app: environment: - DB_HOST=postgres - DB_NAME=database - DB_USER=root - DB_PASSWORD=root
内容的提问来源于stack exchange,提问作者renatompf
相关产品推荐
相关产品推荐

