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

Docker网络中Spring Boot自动配置Elasticsearch失败问题

Docker网络中Spring Boot自动配置Elasticsearch无法解析容器DNS的问题及解决

问题背景

在Docker网络中部署了spring_app、hosting_db(MySQL)、elastic_search三个容器:

  • 直接用curl可正常连接elastic_search容器
  • 禁用Spring自动配置、手动编写RestHighLevelClient Bean时,spring_app能成功连接Elasticsearch
  • 但启用自动配置、在application.yml中指定elastic_search:9200时,Spring会忽略该配置,转而使用localhost,无法解析Elasticsearch的容器DNS名称

使用的依赖:org.springframework.boot:spring-boot-starter-data-elasticsearch

初始无效配置

spring:
  data:
    elasticsearch:
      cluster-nodes: elastic_search:9200
      repositories:
        enabled: true
      conversions:
        enabled: true

后续尝试

发现使用IP地址时配置可正常工作:

spring:
  elasticsearch:
    uris: http://172.16.255.2:${ELASTIC_PORT}, http://172.16.255.3:${ELASTIC_PORT}, http://172.16.255.4:${ELASTIC_PORT}
    connection-timeout: 5s
    socket-timeout: 10s
    sniff: false

但MySQL配置使用容器DNS名称hosting_db完全正常:

spring:
  datasource:
    username: ${MYSQL_USER}
    password: ${MYSQL_PASSWORD}
    url: jdbc:mysql://hosting_db:3306/${MYSQL_DATABASE}

Docker Compose配置

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: hosting_db
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    ports:
      - "3307:3306"
    volumes:
      - "mysql_volume:/var/lib/mysql"
    networks:
      - spring_boot_network

  spring:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: spring_app
    env_file:
      - .env
    depends_on:
      - mysql
      - elastic
    volumes:
      - "${HOSTING_APP_LOCATION}/spring_conf:/app/spring_conf"
      - "spring_storage:/app/spring_storage"
    ports:
      - "${HOSTING_PORT}:${HOSTING_PORT}"
    environment:
      SPRING_CONFIG_LOCATION: "file:/app/spring_conf/application.yml"
    networks:
      - spring_boot_network

  elastic:
    container_name: elastic_search
    image: elasticsearch:8.16.2
    ports:
      - "${ELASTIC_PORT}:${ELASTIC_PORT}"
    volumes:
      - "elastic_volume:/usr/share/elasticsearch/data"
    environment:
      - "discovery.type=single-node"
      - "xpack.security.enabled=false"
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    networks:
      - spring_boot_network

volumes:
  mysql_volume:
  spring_storage:
  elastic_volume:

networks:
  spring_boot_network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: "172.16.255.0/24"
          gateway: "172.16.255.1"

解决方法

问题根源在于Spring Boot版本与Elasticsearch自动配置属性的匹配问题:

  1. 旧属性spring.data.elasticsearch.cluster-nodes是针对已废弃的TransportClient设计的,而当前使用的Elasticsearch 8.x对应的Spring Boot自动配置已切换为基于RestClient的实现,需使用spring.elasticsearch.uris属性
  2. 使用容器DNS名称时,必须加上协议前缀(http://或https://),否则自动配置会识别为无效配置, fallback到默认的localhost:9200

正确的自动配置配置如下:

spring:
  elasticsearch:
    uris: http://elastic_search:${ELASTIC_PORT}
    connection-timeout: 5s
    socket-timeout: 10s
    sniff: false
  data:
    elasticsearch:
      repositories:
        enabled: true
      conversions:
        enabled: true

至于MySQL配置可直接用容器名的原因:JDBC URL本身要求带协议前缀(jdbc:mysql://),Spring数据源解析时会直接将hosting_db作为主机名解析,Docker网络内部的DNS服务可正常解析该容器名,因此无问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:05:14