Search code examples
springdockerelasticsearch

Can't configure elastic search with spring boot in docker network


I have a docker network with several containers: spring_app,hosting_db(mysql),elastic_search. I successfully connect to elastic_search via curl. Also I successfully connect to elastic_search from spring_app when I disable auto configuration and write configuration beans myself. But when I try to specify url in application.yml without beans it seams it ignores url and use localhost. I tried different options to set elastic_search:9200 but spring "thinks" I want localhost and doesn't resolve elastic container's name. Why so? I use org.springframework.boot:spring-boot-starter-data-elasticsearch dependency. My application.yml

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

I can't find valid properties names to set up elastic search. What properties should I use not to create RestHighLevelClient bean myself and use autoconfiguraton?

UPDATE I figured out that elastic_search dns name is not resolved because when I specify ip-addresses everything works fine in this configuration:

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

But I still don't understand why can't spring boot resolve dns name here because I also specified a dns name in mysql configuration and it works fine there

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

where hosting_db is also a container dns name. My docker-compose.yml

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"

SOLVED I solved the problem. I explained how I did it in my answer to this question.


Solution

  • I solved the problem by using elastic (service name) as a hostname for elastic server uri insted of elastic_search (container name). Updated application.yml

    spring:
      elasticsearch:
        uris: http://elastic:${ELASTIC_PORT}
        connection-timeout: 5s
        socket-timeout: 10s
        sniff: false