Problem with DockerComposeContainer

I am trying to set up ElasticSearch with DockerComposeContainer. This works. But when I try to insert a document into ElasticSearch, I get org.apache.http.ConnectionClosedException: Connection closed. It seems to me that the only way to avoid that error is to stop the program flow with a breakpoint and then run the command to insert a document in the debugging mode. I tried adding Thread.sleep(15000) before inserting the document, but it had no effect.

I am using java 1.8, MacBook Pro OS X version 10.11.6, 2.6 GHz Intel Core i5 processor, 8 GB 1600 MHz DDR3 memory

Help with this issue would be much appreciated.

import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.ClassRule;
import org.junit.Test;
import org.testcontainers.containers.DockerComposeContainer;
import java.io.File;

public class RepositoryTest {
    @ClassRule
    public static DockerComposeContainer elasticContainer =
            new DockerComposeContainer(new File("docker-compose.yml"))
                    .withExposedService("elasticsearch_1", 9200)
                    .withExposedService("elasticsearch_1", 9300);

    @Test
    public void test() throws Exception {
        RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200, "http")).build();
        RestHighLevelClient client = new RestHighLevelClient(restClient);
        IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
                .source("user", "kimchy");
        try {
            client.index(indexRequest);
        } catch (Exception e) {
            System.out.println("");
        }

    }
}

docker-compose.yml:

version: "2"
services:
  elasticsearch:
    image: "docker.elastic.co/elasticsearch/elasticsearch:5.6.2"
    environment:
      network.host: "0.0.0.0"
      xpack.security.enabled: "false"
      transport.host: "0.0.0.0"
      http.host: "0.0.0.0"
      network.publish_host: "127.0.0.1"
      transport.tcp.port: "9300"
      discovery.zen.minimum_master_nodes: "1"
      discovery.type: "single-node"
      client.transport.sniff: "false"
    ports:
      - "9200:9200"
      - "9300:9300"

The logs are available in the pastebin.

I believe this might be because elasticsearch takes some time to start (maybe 10 seconds), and you might be connecting too soon. As a result, when your client connect, the TCP connection is immediately closed by Docker.

(If ES was running directly on your machine, you would get "connection refused," but since it is running in a container on OSX, you connect to the Docker proxy, which accepts the connection, but closes it immediately as the backend is not accepting connections yet.)

Here are a few ideas:

  • add a pause before connecting (to check if this hypothesis is correct)
  • if it is the case, add a loop that will patiently try again the connection until you get the ES API
  • or watch the container's logs to detect the message indicating that it's now accepting connections

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.