Docker中Spring Boot容器无法连接PostgreSQL容器问题求助
核心排查步骤
验证容器网络连通性
进入Spring Boot容器,执行ping postgres或nslookup postgres,检查是否能解析到PostgreSQL容器的IP。如果解析失败,说明两个容器不在同一Docker网络中。默认Docker Compose会为所有服务创建默认网络,若手动指定了自定义网络,需检查配置是否存在隔离问题。确认depends_on的局限性
depends_on: [postgres]仅保证postgres容器先启动,不代表PostgreSQL服务已完全就绪(比如数据库初始化未完成)。Spring Boot启动时若数据库未准备好,会抛出连接错误,外观类似DNS解析失败。可通过docker logs postgres查看日志,确认是否出现database system is ready to accept connections标识。检查环境变量覆盖优先级
Spring Boot中环境变量优先级高于application.yaml配置。进入容器执行echo $SPRING_DATASOURCE_URL,确认输出的URL主机名是否为postgres,排查是否被.env文件变量意外覆盖。核对PostgreSQL容器hostname配置
执行docker exec postgres hostname,确认容器实际hostname为postgres,与docker-compose.yml中配置一致。
具体解决方法
添加容器健康检查与等待机制
修改docker-compose.yml,为postgres服务添加健康检查,让app容器等待postgres就绪后再启动:postgres: hostname: postgres image: postgres:13 container_name: postgres restart: always environment: POSTGRES_USER: ${DATABASE_USERNAME} POSTGRES_PASSWORD: ${DATABASE_PASSWORD} POSTGRES_DB: ${DATABASE_NAME_TEST} ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME} -d ${DATABASE_NAME_TEST}"] interval: 5s timeout: 5s retries: 5同时更新app服务的depends_on配置:
app: # 其他原有配置 depends_on: postgres: condition: service_healthy mongo: condition: service_started注:Mongo服务也可添加类似健康检查,避免同类问题。
配置Spring Boot数据库连接重试
在application.yaml的数据源配置中添加HikariCP重试参数:spring: datasource: # 其他原有配置 hikari: maximum-pool-size: 5 connection-timeout: 30000 validation-timeout: 5000 connection-test-query: SELECT 1 initialization-fail-timeout: 0 # 无限等待直到连接成功校验.env文件变量
检查.env文件中DATABASE_HOST是否被错误设置为localhost或其他值,确保PostgreSQL的数据源URL未被意外覆盖。修复Docker网络隔离问题
若ping postgres失败,检查容器所属网络:# 查看所有Docker网络 docker network ls # 查看postgres容器所属网络 docker inspect postgres | grep Networks # 查看app容器所属网络 docker inspect app | grep Networks确保两个容器在同一网络,若存在隔离问题,可重建容器:
docker-compose down -v && docker-compose up --build
内容的提问来源于stack exchange,提问作者Ninho

