Connecting to port 9300 running inside a Docker container

I think I have the same issue as here:

But I am not sure how to implement the fix.

Elastic (5.4.3) running in Docker, started with docker-compose.
The relevant part of the docker-compose is:

my-elastic:
    image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
    container_name: my-elastic
    environment:
        - cluster.name=elasticsearch
        - xpack.security.enabled=false
        - discovery.type=single-node
        - bootstrap.memory_lock=true
        - "ES_JAVA_OPTS=-Xms1024m -Xmx3g"
    ulimits:
        memlock:
            soft: -1
            hard: -1
    mem_limit: 4g
    volumes:
        - ../../data/elasticsearch/data:/usr/share/elasticsearch/data
    ports:
        - 9200:9200
        - 9300:9300

When running a Java container as part of the docker-compose, it has no problem connecting to the elastic cluster (using port 9300 - an older connector; disclaimer: I didn't write the app, but I have to fix it).

However, when trying to run the java container on the host:

Adding transport node: localhost:9300
...
org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{MyNFks6oRdCFAS0LRj3rRQ}{localhost}{127.0.0.1:9300}]

I tried adding

        - network.bind_host=0.0.0.0

to the environment, but it didn't help.

Any help would be greatly appreciated.

Thanks.

How do you build the TransportClient?

public static Client createTransportClient(String clusterNodes, String clusterName) throws Exception {
    logger.info("Creating Elasticsearch transport client");
    Settings settings = Settings.builder().put("cluster.name", clusterName).put("client.transport.sniff", true).build();
    TransportClient client = new PreBuiltTransportClient(settings);

    if (StringUtils.isNotEmpty(clusterNodes)) {
        for (String clusterNode : StringUtils.split(clusterNodes, ',')) {
            String hostName = StringUtils.substringBeforeLast(clusterNode, ":");
            String port = StringUtils.substringAfterLast(clusterNode, ":");
            Assert.hasText(hostName, "[Assertion failed] missing host name in 'clusterNodes'");
            Assert.hasText(port, "[Assertion failed] missing port in 'clusterNodes'");
            logger.info("Adding transport node: " + clusterNode);
            client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(hostName), Integer.valueOf(port)));
        }
        client.connectedNodes();
    }
    logger.info(client.admin().cluster().prepareHealth().get().toString());
    return client;
}

Disclaimer: this is not my code and I am rather new to Elasticsearch, so I don't know if this code is good or bad.

Thanks for your help.

What is the value for clusterName?

elasticsearch

Hi @dadoonet,

the clusterName is elasticsearch.

Is there any hope for me to fix this please ?

Thank you.

It looks good. May be a firewall issue with port 9300 which is actually blocked?

Could you share the logs of your elasticsearch instance?

Seems like the issue is caused by client.transport.sniff set to true.

Settings settings = Settings.builder()
                            .put("cluster.name", clusterName)
//                                    .put("client.transport.sniff", true)
                        .build();
TransportClient client = new PreBuiltTransportClient(settings);

I have commented out that line and now it works.

However, I would still like to understand why.

It seems that a lot of people complained about not being able to connect to Docker containers and also there are lots of issues with the client.transport.sniff.

But despite reading a whole bunch of issues and replies and such, I still couldn't find an explanation. Which part of what client.transport.sniff does causes the issue ?

Regardless of whether you can answer this question, thank you for your help.