Elasticsearch is an open-source, distributed search and analytics engine built on Apache Lucene. It is the core component of the Elastic Stack (formerly ELK Stack), which includes Logstash for data processing and Kibana for visualization. Elasticsearch handles full-text search, log analytics, infrastructure monitoring, and application performance data at scale.

In this guide, I will walk you through installing Elasticsearch 8.x on Ubuntu 24.04 or Ubuntu 22.04. Version 8.x ships with security enabled by default, bundled Java, and several performance improvements over earlier releases.

Prerequisites

Before you begin, make sure you have the following in place:

  • A server running Ubuntu 24.04 or 22.04 with root or sudo access
  • At least 2 GB of RAM (4 GB or more recommended for production)
  • A stable internet connection to download packages

One thing worth noting – Elasticsearch 8.x ships with a bundled JDK. You no longer need to install Java separately. The bundled JDK is tested and supported by Elastic, so there is no reason to override it unless you have a specific requirement.

Step 1 – Update the System

Start by updating your package index and upgrading installed packages:

sudo apt update && sudo apt upgrade -y

Install required dependencies for adding external repositories:

sudo apt install -y apt-transport-https curl gnupg

Step 2 – Import the Elasticsearch GPG Key and Add the APT Repository

Import the Elastic GPG signing key:

curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

Add the Elastic 8.x APT repository:

echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list

Verify the repository file was created:

cat /etc/apt/sources.list.d/elastic-8.x.list

You should see the repository line pointing to artifacts.elastic.co.

Step 3 – Install Elasticsearch 8.x

Update the package index and install Elasticsearch:

sudo apt update
sudo apt install -y elasticsearch

Important: During installation, Elasticsearch 8.x prints security configuration details to the terminal. This includes the auto-generated password for the elastic superuser and an enrollment token for Kibana. Copy and save this output – you will need it later.

The output looks similar to this:

--------------------------- Security autoconfiguration information ------------------------------
Authentication and authorization are enabled.
TLS for the transport and HTTP layers is enabled and configured.

The generated password for the elastic built-in superuser is : <your-password-here>

If this node should join an existing cluster, you can reconfigure this with
'/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <token-here>'
-------------------------------------------------------------------------------------------------

If you missed the output, you can reset the elastic user password later with:

sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

Verify the installed version:

sudo /usr/share/elasticsearch/bin/elasticsearch --version

Step 4 – Configure Elasticsearch

The main configuration file is located at /etc/elasticsearch/elasticsearch.yml. Open it with your preferred editor:

sudo nano /etc/elasticsearch/elasticsearch.yml

Here are the key settings you should review and adjust:

Cluster and Node Name

Give your cluster and node descriptive names:

cluster.name: my-cluster
node.name: node-1

Network Binding

By default, Elasticsearch binds to localhost. If you need to access it from other machines, change the network host:

network.host: 0.0.0.0
http.port: 9200

If you set network.host to anything other than localhost, Elasticsearch enters production mode and enforces bootstrap checks. Make sure your system meets the requirements before doing this.

Discovery Settings

For a multi-node cluster, configure the seed hosts and initial master nodes:

discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

For a single-node setup (development or testing), use this instead:

discovery.type: single-node

This tells Elasticsearch not to look for other nodes and skips the bootstrap checks related to cluster formation.

Data and Log Paths

The defaults work fine for most setups, but you can change them if needed:

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

Step 5 – Configure JVM Heap Size

Elasticsearch runs on the JVM, and you should tune the heap size based on your available memory. The configuration file is at /etc/elasticsearch/jvm.options.

Instead of editing the main file directly, create a custom options file:

sudo nano /etc/elasticsearch/jvm.options.d/heap.options

Add the following (adjust the values to your server – a common rule is to set heap to half of available RAM, but never more than 31 GB):

-Xms2g
-Xmx2g

Both values should be identical to avoid performance issues from heap resizing. On a server with 4 GB of RAM, setting 2 GB for the heap is a good starting point.

Step 6 – Start and Enable Elasticsearch

Reload the systemd daemon, then enable and start the Elasticsearch service:

sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch

Verify the service is running:

sudo systemctl status elasticsearch

You should see active (running) in the output. If the service fails to start, check the logs:

sudo journalctl -u elasticsearch --no-pager -n 50

Step 7 – Verify Elasticsearch is Working

Since Elasticsearch 8.x enables HTTPS by default, you need to use https and authenticate when testing:

curl -k -u elastic:<your-password> https://localhost:9200

You should get a JSON response showing the cluster name, version, and tagline:

{
  "name" : "node-1",
  "cluster_name" : "my-cluster",
  "cluster_uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "version" : {
    "number" : "8.x.x",
    "build_flavor" : "default",
    "build_type" : "deb",
    ...
  },
  "tagline" : "You Know, for Search"
}

If you prefer to test without HTTPS (for development), you can disable security in elasticsearch.yml:

xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false

After disabling security, restart the service and test with plain HTTP:

sudo systemctl restart elasticsearch
curl http://localhost:9200

Warning: Never disable security on a production system.

Step 8 – Security Features in Elasticsearch 8.x

Elasticsearch 8.x enables security by default. Here is what that means in practice:

  • TLS/SSL is enabled on both the HTTP and transport layers out of the box
  • Authentication is required – the elastic superuser password is generated during installation
  • Enrollment tokens allow you to securely connect Kibana and other Elasticsearch nodes to the cluster

To generate an enrollment token for Kibana:

sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana

To generate an enrollment token for another Elasticsearch node joining the cluster:

sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node

Step 9 – Configure the Firewall

If you are running UFW (the default firewall on Ubuntu), open the ports used by Elasticsearch:

  • Port 9200 – HTTP API (client communication)
  • Port 9300 – Transport (node-to-node communication in a cluster)
sudo ufw allow 9200/tcp
sudo ufw allow 9300/tcp
sudo ufw reload

If this is a single-node setup that only needs local access, you can skip opening these ports. Only open port 9300 if you are running a multi-node cluster.

Verify the firewall rules:

sudo ufw status numbered

Step 10 – Basic Index CRUD Operations

Now that Elasticsearch is running, here are some basic operations to get you started. These examples assume security is enabled, so we pass credentials with each request.

Create an Index

curl -k -u elastic:<your-password> -X PUT "https://localhost:9200/my-first-index?pretty"

Index a Document

curl -k -u elastic:<your-password> -X POST "https://localhost:9200/my-first-index/_doc/1?pretty" \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Getting started with Elasticsearch",
    "author": "admin",
    "date": "2026-03-18"
  }'

Retrieve a Document

curl -k -u elastic:<your-password> -X GET "https://localhost:9200/my-first-index/_doc/1?pretty"

Update a Document

curl -k -u elastic:<your-password> -X POST "https://localhost:9200/my-first-index/_update/1?pretty" \
  -H 'Content-Type: application/json' \
  -d '{
    "doc": {
      "title": "Getting started with Elasticsearch 8.x"
    }
  }'

Delete a Document

curl -k -u elastic:<your-password> -X DELETE "https://localhost:9200/my-first-index/_doc/1?pretty"

Delete an Index

curl -k -u elastic:<your-password> -X DELETE "https://localhost:9200/my-first-index?pretty"

List All Indices

curl -k -u elastic:<your-password> -X GET "https://localhost:9200/_cat/indices?v"

Configuring Elasticsearch for Single-Node vs Cluster

Single-Node Configuration

For development, testing, or small workloads where you only need one Elasticsearch instance, add this to /etc/elasticsearch/elasticsearch.yml:

cluster.name: my-single-node
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node

This skips the cluster bootstrap process and runs Elasticsearch as a standalone instance.

Multi-Node Cluster Configuration

For a production cluster with three nodes, each node needs its own configuration. Here is an example for the first node:

cluster.name: production-cluster
node.name: es-node-1
network.host: 192.168.1.10
http.port: 9200
discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]

Repeat the installation on each node, adjusting node.name and network.host accordingly. Use enrollment tokens to join additional nodes to the cluster securely.

Troubleshooting

Elasticsearch fails to start

Check the logs first:

sudo journalctl -u elasticsearch --no-pager -n 100
sudo cat /var/log/elasticsearch/my-cluster.log

Bootstrap checks failed

If you see errors about bootstrap checks when binding to a non-localhost address, you likely need to adjust system limits. Add the following to /etc/security/limits.conf:

elasticsearch  -  nofile  65535
elasticsearch  -  nproc   4096

Also set the virtual memory map count:

sudo sysctl -w vm.max_map_count=262144

To make it persistent across reboots:

echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Out of memory errors

If Elasticsearch is killed by the OOM killer, reduce the heap size in /etc/elasticsearch/jvm.options.d/heap.options. Make sure the heap does not exceed half of your total RAM, and leave enough memory for the operating system and file system cache.

Connection refused on port 9200

Verify the service is running and listening:

sudo systemctl status elasticsearch
sudo ss -tlnp | grep 9200

If the port is not listening, check the network.host setting in elasticsearch.yml and review the logs for startup errors.

Certificate or SSL errors

Since 8.x enables TLS by default, make sure you are using https:// in your requests. If you get certificate verification errors with curl, use the -k flag to skip verification, or point curl to the CA certificate:

curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:<your-password> https://localhost:9200

Forgot the elastic user password

Reset it with:

sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

Cluster health is yellow or red

Check the cluster health endpoint:

curl -k -u elastic:<your-password> "https://localhost:9200/_cluster/health?pretty"

Yellow status on a single-node cluster is expected because replica shards cannot be allocated to the same node. For a single-node setup, you can set replicas to zero for your indices:

curl -k -u elastic:<your-password> -X PUT "https://localhost:9200/_settings?pretty" \
  -H 'Content-Type: application/json' \
  -d '{"index": {"number_of_replicas": 0}}'

Conclusion

You now have Elasticsearch 8.x installed and running on Ubuntu 24.04 or 22.04. The key differences from earlier versions are that security is enabled out of the box – TLS, authentication, and enrollment tokens are all configured automatically during installation. Java is bundled with the package, removing one of the common setup headaches from the old days.

From here, you can install Kibana for a web-based interface, set up Logstash or Beats for data ingestion, or start building your search and analytics workflows directly through the REST API.

LEAVE A REPLY

Please enter your comment!
Please enter your name here