# How to setup a multi-node elasticsearch cluster in separate machines with ip specified in docker-compose.yml

**URL:** <https://discuss.elastic.co/t/how-to-setup-a-multi-node-elasticsearch-cluster-in-separate-machines-with-ip-specified-in-docker-compose-yml/352854>\
**Category:** Elasticsearch\
**Tags:** elastic-stack-security, docker\
**Created:** [February 8, 2024, 11:43am UTC](https://discuss.elastic.co/t/how-to-setup-a-multi-node-elasticsearch-cluster-in-separate-machines-with-ip-specified-in-docker-compose-yml/352854 "2024-02-08T11:43:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![elasticheart](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/elasticheart/32/65189_2.png) [@elasticheart](https://discuss.elastic.co/u/elasticheart)\
**Post date:** [February 8, 2024, 11:43am UTC](https://discuss.elastic.co/t/how-to-setup-a-multi-node-elasticsearch-cluster-in-separate-machines-with-ip-specified-in-docker-compose-yml/352854/1 "2024-02-08T11:43:22Z")

</div>

Hi guys,

I would like to setup a multi-node elasticsearch v8.11.4 cluster using docker compose, **"not in a single machine / host"**. I have 3 machines with IP 192.168.0.101, 192.168.0.102 and 192.168.0.103, and I want my nodes to be there.

I created the `docker-compose.yml` and `.env` files as mentioned in the offiial documentation, as follows;

**docker-compose.yml**

```auto
version: "2.2"

services:
  setup:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
    user: "0"
    command: >
      bash -c '
        if [x${ELASTIC_PASSWORD} == x]; then
          echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
          exit 1;
        elif [x${KIBANA_PASSWORD} == x]; then
          echo "Set the KIBANA_PASSWORD environment variable in the .env file";
          exit 1;
        fi;
        if [! -f config/certs/ca.zip]; then
          echo "Creating CA";
          bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
          unzip config/certs/ca.zip -d config/certs;
        fi;
        if [! -f config/certs/certs.zip]; then
          echo "Creating certs";
          echo -ne \
          "instances:\n"\
          " - name: es01\n"\
          " dns:\n"\
          " - es01\n"\
          " - localhost\n"\
          " ip:\n"\
          " - 127.0.0.1\n"\
          " - ${IP_ELASTIC_NODE_1}\n"\
          " - name: es02\n"\
          " dns:\n"\
          " - es02\n"\
          " - localhost\n"\
          " ip:\n"\
          " - 127.0.0.1\n"\
          " - ${IP_ELASTIC_NODE_2}\n"\
          " - name: es03\n"\
          " dns:\n"\
          " - es03\n"\
          " - localhost\n"\
          " ip:\n"\
          " - 127.0.0.1\n"\
          " - ${IP_ELASTIC_NODE_3}\n"\
          > config/certs/instances.yml;
          bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
          unzip config/certs/certs.zip -d config/certs;
        fi;
        echo "Setting file permissions"
        chown -R root:root config/certs;
        find . -type d -exec chmod 750 \{\} \;;
        find . -type f -exec chmod 640 \{\} \;;
        echo "Waiting for Elasticsearch availability";
        until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
        echo "Setting kibana_system password";
        until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done;
        echo "All done!";
      '
    healthcheck:
      test: ["CMD-SHELL", "[-f config/certs/es01/es01.crt]"]
      interval: 1s
      timeout: 5s
      retries: 120

  es01:
    depends_on:
      setup:
        condition: service_healthy
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata:/usr/share/elasticsearch/data
    ports:
      - ${ES_PORT}:9200
      - ${ES_SERVICE_PORT}:9300
    environment:
      - node.name=es01
      - cluster.name=${CLUSTER_NAME}
      - cluster.initial_master_nodes=es01,es02,es03
      - discovery.seed_hosts=${IP_ELASTIC_NODE_2},${IP_ELASTIC_NODE_3}
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/es01/es01.key
      - xpack.security.http.ssl.certificate=certs/es01/es01.crt
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/es01/es01.key
      - xpack.security.transport.ssl.certificate=certs/es01/es01.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.license.self_generated.type=${LICENSE}
      - network.publish_host=${IP_ELASTIC_NODE_1}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s --cacert config/certs/ca/ca.crt https://${IP_ELASTIC_NODE_1}:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

  es02:
    depends_on:
      - es01
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata:/usr/share/elasticsearch/data
    ports:
      - ${ES_PORT}:9200
      - ${ES_SERVICE_PORT}:9300
    environment:
      - node.name=es02
      - cluster.name=${CLUSTER_NAME}
      - cluster.initial_master_nodes=es01,es02,es03
      - discovery.seed_hosts=${IP_ELASTIC_NODE_1},${IP_ELASTIC_NODE_3}
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/es02/es02.key
      - xpack.security.http.ssl.certificate=certs/es02/es02.crt
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/es02/es02.key
      - xpack.security.transport.ssl.certificate=certs/es02/es02.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.license.self_generated.type=${LICENSE}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s --cacert config/certs/ca/ca.crt https://${IP_ELASTIC_NODE_2}:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

  es03:
    depends_on:
      - es02
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata:/usr/share/elasticsearch/data
    ports:
      - ${ES_PORT}:9200
      - ${ES_SERVICE_PORT}:9300
    environment:
      - node.name=es03
      - cluster.name=${CLUSTER_NAME}
      - cluster.initial_master_nodes=es01,es02,es03
      - discovery.seed_hosts=${IP_ELASTIC_NODE_1},${IP_ELASTIC_NODE_2}
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/es03/es03.key
      - xpack.security.http.ssl.certificate=certs/es03/es03.crt
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/es03/es03.key
      - xpack.security.transport.ssl.certificate=certs/es03/es03.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.license.self_generated.type=${LICENSE}
      - network.publish_host=${IP_ELASTIC_NODE_3}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s --cacert config/certs/ca/ca.crt https://${IP_ELASTIC_NODE_3}:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

volumes:
  certs:
    driver: local
    driver_opts:
      type: none
      device: "/data/elasticsearch/certs"
      o: bind
  esdata:
    driver: local
    driver_opts:
      type: none
      device: "/data/elasticsearch/data"
      o: bind

```

**.env**

```auto
IP_ELASTIC_NODE_1=192.168.0.101
IP_ELASTIC_NODE_2=192.168.0.102
IP_ELASTIC_NODE_3=192.168.0.103
ELASTIC_PASSWORD=password
KIBANA_PASSWORD=password
STACK_VERSION=8.11.4
CLUSTER_NAME=my-cluster
LICENSE=basic
ES_PORT=9200
ES_SERVICE_PORT=9300
MEM_LIMIT=2147483648

```

I would like to discover my cluster using the IPs 192.168.0.101, 192.168.0.102, and 192.168.0.103. I built my first node using command `sudo docker-compose up es01`. When I tried to curl the node using command `curl https://192.168.0.101:9200/_cat/health` , I got no response, but the container was running.

Could somebody please help me to fix the docker file?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![leandrojmp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/leandrojmp/32/107231_2.png) [@leandrojmp](https://discuss.elastic.co/u/leandrojmp)\
**Post date:** [February 8, 2024, 12:12pm UTC](https://discuss.elastic.co/t/how-to-setup-a-multi-node-elasticsearch-cluster-in-separate-machines-with-ip-specified-in-docker-compose-yml/352854/2 "2024-02-08T12:12:15Z")

</div>

If you have 3 different hosts, why your docker compose is spinning up 3 servers?

You need a docker compose on each server, and each one of them will start just one elasticsearch node.

Also, since you have 3 different hosts, it is a little more complicated as you will need to create the certificates and copy them to other hosts and then bind the path with certificates in your docker compose.

I do not use docker, but this is what you need to try to implement, what you shared is a docker compose to spin up 3 nodes on the same cluster, but it will not work because the IP address you are using is different.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [March 7, 2024, 12:12pm UTC](https://discuss.elastic.co/t/how-to-setup-a-multi-node-elasticsearch-cluster-in-separate-machines-with-ip-specified-in-docker-compose-yml/352854/3 "2024-03-07T12:12:45Z")

</div>

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