Docker Compose中Spring Boot容器无法连接同网络MongoDB:连接被拒绝
核心问题定位
从你提供的MongoClient配置日志可以看到,clusterSettings里的hosts是[localhost:27017],但你在application.properties里指定的是mongodb:27017,说明你的自定义MongoDB配置没有正确读取application.properties中的连接配置,导致Spring Boot使用了MongoClient的默认连接地址。
具体修复步骤
1. 修正自定义MongoDB配置类
你的MongoDBConfig直接注入的MongoClient是Spring自动配置生成的默认实例(默认连localhost),而非基于你配置的uri生成的。修改配置类,手动基于配置属性构建MongoClient:
@Configuration @EnableMongoRepositories(basePackageClasses = [ // 你的repo类 ]) class MongoDBConfig( @Value("\${spring.data.mongodb.uri}") private val mongoUri: String ){ @Bean fun mongoClient(): MongoClient { return MongoClients.create(mongoUri) } @Bean fun mongoTemplate(): MongoTemplate { return MongoTemplate(mongoClient(), "oasis") } }
同时移除@Import(value = [MongoAutoConfiguration::class]),因为@EnableMongoRepositories已经会触发Spring的Mongo自动配置逻辑,手动导入反而可能导致配置冲突。
2. 确保application.properties被正确加载
检查你的Dockerfile,确认application.properties被正确复制到镜像的resources目录下,比如Dockerfile里应有类似命令:
COPY src/main/resources/application.properties /app/resources/
如果使用多环境配置,还要确认启动时加载的是正确的配置文件(比如没有通过环境变量SPRING_PROFILES_ACTIVE切换到未配置Mongo地址的profile)。
3. 完善Docker Compose的依赖与健康检查
depends_on仅保证启动顺序,不保证MongoDB服务就绪。给MongoDB服务添加健康检查,让应用在MongoDB真正可用后再启动:
services: mongodb: # 其他配置不变 healthcheck: test: ["CMD", "mongo", "--eval", "db.adminCommand('ping')"] interval: 5s timeout: 5s retries: 5 application: # 其他配置不变 depends_on: mongodb: condition: service_healthy
这样可以避免应用在MongoDB初始化完成前就尝试连接。
4. 验证Docker网络连通性
Docker Compose默认会给所有服务创建自定义网络,服务间可通过服务名(mongodb)访问。进入应用容器,测试是否能ping通mongodb服务:
docker exec -it application ping mongodb
如果ping不通,检查是否有自定义网络配置冲突,或容器是否在同一网络中。
补充说明
你提到用network_mode: host能解决连接问题,但Windows下不支持——这是因为host模式下容器直接使用宿主机网络,此时localhost指向宿主机,而宿主机的MongoDB端口已映射到27017,所以能连接。但这不是标准容器化部署方式,上述修复步骤才是合规解决方案。
内容的提问来源于stack exchange,提问作者Sergio Arcos

