output {\n elasticsearch {\n hosts => [\"https:\/\/${NODE1_NAME}:9200\",\"https:\/\/${NODE2_NAME}:9200\", \"https:\/\/${NODE3_NAME}:9200\"]\n user => \"${ELASTICSEARCH_USERNAME}\"\n password => \"${ELASTICSEARCH_PASSWORD}\"\n ssl => true\n cacert => \"config\/certs\/ca\/ca.crt\"\n \n<\/code><\/pre>\n\n\n\nCreate Docker-Compose file for your Container Services<\/h4>\n\n\n\n
We will be using three nodes in this setup. On each node, we will run a single Docker container of ELK stack components, Elasticsearch 8, Logstash 8, Kibana 8. We will later on connect the Elasticsearch 8 containers together to make a cluster.<\/p>\n\n\n\n
Thus, on the first node, let’s create a Docker compose file for our ELK stack.<\/p>\n\n\n\n
mkdir elkstack-docker<\/code><\/pre>\n\n\n\ncd elkstack-docker<\/code><\/pre>\n\n\n\nvim docker-compose.yml<\/code><\/pre>\n\n\n\nBelow is a sample Docker compose file configs for first node of our ELK Stack 8 Cluster Docker container.<\/p>\n\n\n\n
version: '3.8'\n\nservices:\n es_setup:\n image: docker.elastic.co\/elasticsearch\/elasticsearch:${STACK_VERSION}\n volumes:\n - certs:\/usr\/share\/elasticsearch\/config\/certs\n user: \"0\"\n command: >\n bash -c '\n echo \"Creating ES certs directory...\"\n [[ -d config\/certs ]] || mkdir config\/certs\n # Check if CA certificate exists\n if [ ! -f config\/certs\/ca\/ca.crt ]; then\n echo \"Generating Wildcard SSL certs for ES (in PEM format)...\"\n bin\/elasticsearch-certutil ca --pem --days 3650 --out config\/certs\/elkstack-ca.zip\n unzip -d config\/certs config\/certs\/elkstack-ca.zip\n bin\/elasticsearch-certutil cert \\\n --name elkstack-certs \\\n --ca-cert config\/certs\/ca\/ca.crt \\\n --ca-key config\/certs\/ca\/ca.key \\\n --pem \\\n --dns \"*.${DOMAIN_SUFFIX},localhost,${NODE1_NAME},${NODE2_NAME},${NODE3_NAME}\" \\\n --ip 192.168.122.60 \\\n --ip 192.168.122.123 \\\n --ip 192.168.122.152 \\\n --days ${DAYS} \\\n --out config\/certs\/elkstack-certs.zip\n unzip -d config\/certs config\/certs\/elkstack-certs.zip\n else\n echo \"CA certificate already exists. Skipping Certificates generation.\"\n fi\n # Check if Elasticsearch is ready\n until curl -s --cacert config\/certs\/ca\/ca.crt -u \"elastic:${ELASTIC_PASSWORD}\" https:\/\/${NODE1_NAME}:9200 | grep -q \"${CLUSTER_NAME}\"; do sleep 10; done\n # Set kibana_system password\n if curl -sk -XGET --cacert config\/certs\/ca\/ca.crt \"https:\/\/${NODE1_NAME}:9200\" -u \"kibana_system:${KIBANA_PASSWORD}\" | grep -q \"${CLUSTER_NAME}\"; then\n echo \"Password for kibana_system is working. Proceeding with Elasticsearch setup for kibana_system.\"\n else\n echo \"Failed to authenticate with kibana_system password. Trying to set the password for kibana_system.\"\n until curl -s -XPOST --cacert config\/certs\/ca\/ca.crt -u \"elastic:${ELASTIC_PASSWORD}\" -H \"Content-Type: application\/json\" https:\/\/${NODE1_NAME}:9200\/_security\/user\/kibana_system\/_password -d \"{\\\"password\\\":\\\"${KIBANA_PASSWORD}\\\"}\" | grep -q \"^{}\"; do sleep 10; done\n fi\n echo \"Setup is done!\"\n '\n networks:\n - elastic\n healthcheck:\n test: [\"CMD-SHELL\", \"[ -f config\/certs\/elkstack-certs\/elkstack-certs.crt ]\"]\n interval: 1s\n timeout: 5s\n retries: 120\n\n elasticsearch:\n depends_on:\n es_setup:\n condition: service_healthy\n container_name: ${NODE1_NAME}\n image: docker.elastic.co\/elasticsearch\/elasticsearch:${STACK_VERSION}\n environment:\n - node.name=${NODE1_NAME}\n - network.publish_host=${NODE1} \n - cluster.name=${CLUSTER_NAME}\n - bootstrap.memory_lock=true\n - \"ES_JAVA_OPTS=-Xms1g -Xmx1g\"\n - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}\n - xpack.security.enabled=true\n - xpack.security.http.ssl.enabled=true\n - xpack.security.transport.ssl.enabled=true\n - xpack.security.enrollment.enabled=false\n - xpack.security.autoconfiguration.enabled=false\n - xpack.security.http.ssl.key=certs\/elkstack-certs\/elkstack-certs.key\n - xpack.security.http.ssl.certificate=certs\/elkstack-certs\/elkstack-certs.crt\n - xpack.security.http.ssl.certificate_authorities=certs\/ca\/ca.crt\n - xpack.security.transport.ssl.key=certs\/elkstack-certs\/elkstack-certs.key\n - xpack.security.transport.ssl.certificate=certs\/elkstack-certs\/elkstack-certs.crt\n - xpack.security.transport.ssl.certificate_authorities=certs\/ca\/ca.crt\n - cluster.initial_master_nodes=${NODE1_NAME},${NODE2_NAME},${NODE3_NAME}\n - discovery.seed_hosts=192.168.122.60,192.168.122.123,192.168.122.152\n - KIBANA_USERNAME=${KIBANA_USERNAME}\n - KIBANA_PASSWORD=${KIBANA_PASSWORD}\n ulimits:\n memlock:\n soft: -1\n hard: -1\n volumes:\n - elasticsearch_data:\/usr\/share\/elasticsearch\/data\n - certs:\/usr\/share\/elasticsearch\/config\/certs\n - \/etc\/hosts:\/etc\/hosts\n ports:\n - 9200:9200\n - 9300:9300\n networks:\n - elastic\n healthcheck:\n test: [\"CMD-SHELL\", \"curl --fail -k -s -u elastic:${ELASTIC_PASSWORD} --cacert config\/certs\/ca\/ca.crt https:\/\/${NODE1_NAME}:9200\"]\n interval: 30s\n timeout: 10s\n retries: 5\n restart: unless-stopped\n\n kibana:\n image: docker.elastic.co\/kibana\/kibana:${STACK_VERSION}\n container_name: kibana\n environment:\n - SERVER_NAME=${KIBANA_SERVER_HOST}\n - ELASTICSEARCH_HOSTS=https:\/\/${NODE1_NAME}:9200\n - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config\/certs\/ca\/ca.crt\n - ELASTICSEARCH_USERNAME=${KIBANA_USERNAME}\n - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}\n - XPACK_REPORTING_ROLES_ENABLED=false\n - XPACK_REPORTING_KIBANASERVER_HOSTNAME=localhost\n - XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=${SAVEDOBJECTS_ENCRYPTIONKEY}\n - XPACK_SECURITY_ENCRYPTIONKEY=${REPORTING_ENCRYPTIONKEY}\n - XPACK_REPORTING_ENCRYPTIONKEY=${SECURITY_ENCRYPTIONKEY}\n volumes:\n - kibana_data:\/usr\/share\/kibana\/data\n - certs:\/usr\/share\/kibana\/config\/certs\n - \/etc\/hosts:\/etc\/hosts\n ports:\n - ${KIBANA_PORT}:5601\n networks:\n - elastic\n depends_on:\n elasticsearch:\n condition: service_healthy\n restart: unless-stopped\n \n logstash:\n image: docker.elastic.co\/logstash\/logstash:${STACK_VERSION}\n container_name: logstash\n environment:\n - XPACK_MONITORING_ENABLED=false\n - ELASTICSEARCH_USERNAME=${ES_USER}\n - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}\n - NODE_NAME=${NODE1_NAME}\n ports:\n - 5044:5044\n volumes:\n - logstash_filters:\/usr\/share\/logstash\/pipeline\/:ro\n - certs:\/usr\/share\/logstash\/config\/certs\n - logstash_data:\/usr\/share\/logstash\/data\n - \/etc\/hosts:\/etc\/hosts\n networks:\n - elastic\n depends_on:\n elasticsearch:\n condition: service_healthy\n restart: unless-stopped\n\nvolumes:\n certs:\n driver: local\n driver_opts:\n type: nfs\n o: \"addr=192.168.122.60,nfsvers=4,rw\"\n device: \":\/mnt\/elkstack\/certs\"\n elasticsearch_data:\n driver: local\n driver_opts:\n type: nfs\n o: \"addr=192.168.122.60,nfsvers=4,rw\"\n device: \":\/mnt\/elkstack\/data\/elasticsearch\/01\"\n kibana_data:\n driver: local\n driver_opts:\n type: nfs\n o: \"addr=192.168.122.60,nfsvers=4,rw\"\n device: \":\/mnt\/elkstack\/data\/kibana\/01\"\n logstash_filters:\n driver: local\n driver_opts:\n type: nfs\n o: \"addr=192.168.122.60,nfsvers=4,rw\"\n device: \":\/mnt\/elkstack\/configs\/logstash\"\n logstash_data:\n driver: local\n driver_opts:\n type: nfs\n o: \"addr=192.168.122.60,nfsvers=4,rw\"\n device: \":\/mnt\/elkstack\/data\/logstash\/01\"\n\nnetworks:\n elastic:\n<\/code><\/pre>\n\n\n\nWhere:<\/p>\n\n\n\n
\nes_setup<\/code> Service:\n\n- Image:<\/strong> Uses the official Elasticsearch Docker image with a specified version (
${STACK_VERSION}<\/code>).<\/li>\n\n\n\n- Volumes:<\/strong> Mounts a volume named
certs<\/code> to the Elasticsearch configuration directory.<\/li>\n\n\n\n- User:<\/strong> Sets the user to root (user ID 0).<\/li>\n\n\n\n
- Command:<\/strong> Shell script for setting up Elasticsearch certificates, checking cluster readiness, and setting the
kibana_system<\/code> password.<\/li>\n\n\n\n- Networks:<\/strong> Connects to the
elastic<\/code> network.<\/li>\n\n\n\n- Healthcheck:<\/strong> Uses a custom health check to test the existence of a specific file (
config\/certs\/elkstack-certs\/elkstack-certs.crt<\/code>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n\nelasticsearch<\/code> Service:\n\n- Depends On:<\/strong> Depends on the
es_setup<\/code> service with the condition that es_setup<\/code> is healthy.<\/li>\n\n\n\n- Container Name:<\/strong> Specifies a custom name for the Elasticsearch container (
${NODE1_NAME}<\/code>).<\/li>\n\n\n\n- Image:<\/strong> Uses the official Elasticsearch Docker image with the specified version (
${STACK_VERSION}<\/code>).<\/li>\n\n\n\n- Environment:<\/strong> Configures various environment variables for Elasticsearch, such as node name, network settings, security, etc.<\/li>\n\n\n\n
- Ulimits:<\/strong> Sets memory lock limits for Elasticsearch.<\/li>\n\n\n\n
- Volumes:<\/strong> Mounts volumes for Elasticsearch data, certificates, and the hosts file.<\/li>\n\n\n\n
- Ports:<\/strong> Exposes ports 9200 and 9300.<\/li>\n\n\n\n
- Networks:<\/strong> Connects to the
elastic<\/code> network.<\/li>\n\n\n\n- Healthcheck:<\/strong> Uses a custom health check to check Elasticsearch availability.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n
\nkibana<\/code> Service:<\/li>\n<\/ul>\n\n\n\n\n- Image:<\/strong> Uses the official Kibana Docker image with the specified version (
${STACK_VERSION}<\/code>).<\/li>\n\n\n\n- Container Name:<\/strong> Specifies a custom name for the Kibana container (
kibana<\/code>).<\/li>\n\n\n\n- Environment:<\/strong> Configures environment variables for Kibana, including Elasticsearch connection details and security settings.<\/li>\n\n\n\n
- Volumes:<\/strong> Mounts volumes for Kibana data, certificates, and the hosts file.<\/li>\n\n\n\n
- Ports:<\/strong> Exposes the specified port for Kibana.<\/li>\n\n\n\n
- Networks:<\/strong> Connects to the
elastic<\/code> network.<\/li>\n\n\n\n- Depends On:<\/strong> Depends on the
elasticsearch<\/code> service with the condition that elasticsearch<\/code> is healthy.<\/li>\n<\/ul>\n\n\n\n\nLogstash<\/code> Service:\n\n- Image:<\/strong> Uses the official Logstash Docker image with the specified version (
${STACK_VERSION}<\/code>).<\/li>\n\n\n\n- Container Name:<\/strong> Specifies a custom name for the Logstash container (
logstash<\/code>).<\/li>\n\n\n\n- Environment:<\/strong> Configures environment variables for Logstash, including Elasticsearch connection details and security settings.<\/li>\n\n\n\n
- Ports:<\/strong> Exposes port 5044 for Logstash.<\/li>\n\n\n\n
- Volumes:<\/strong> Mounts volumes for Logstash filters, certificates, and Logstash data.<\/li>\n\n\n\n
- Networks:<\/strong> Connects to the
elastic<\/code> network.<\/li>\n\n\n\n- Depends On:<\/strong> Depends on the
elasticsearch<\/code> service with the condition that elasticsearch<\/code> is healthy.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n\n- Volumes:\n
\n- Defines multiple volumes for storing certificates, Elasticsearch data, Kibana data, Logstash filters, and Logstash data. These volumes are configured to use NFS.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n
\n- Networks:\n
\n- Defines a custom network named
elastic<\/code> for connecting the services.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\nAll the environment variables used are defined in the .env<\/strong><\/code> file.<\/p>\n\n\n\n