How to Install Elasticsearch on Ubuntu 26.04 LTS
Elasticsearch remains the backbone of countless search, logging, and observability stacks, and Ubuntu 26.04 LTS (“Resolute Raccoon”) is now a common target for new deployments thanks to its long support window. This guide walks through a clean, production-oriented installation of Elasticsearch on Ubuntu 26.04 using Elastic’s official APT repository, covers the current 8.x vs 9.x decision, and includes hardening, systemd management, and troubleshooting steps you’ll actually need in the field.
Table of Contents
- Elasticsearch 8.x vs 9.x: Which Should You Install?
- Prerequisites
- Architecture Overview
- Step 1: Update the System and Install Dependencies
- Step 2: Import the Elastic GPG Key
- Step 3: Add the Elastic APT Repository
- Step 4: Install Elasticsearch
- Step 5: Save the Auto-Generated Security Credentials
- Step 6: Configure Elasticsearch (elasticsearch.yml)
- Step 7: Tune the JVM Heap Size
- Step 8: Start and Enable the Service
- Step 9: Verify the Installation
- Step 10: Configure the Firewall (UFW)
- Optional: Install Kibana
- Troubleshooting
- Removing Elasticsearch
- Related Reading on bckinfo.com
Elasticsearch 8.x vs 9.x: Which Should You Install?
Elastic currently maintains two active branches side by side. For a fresh deployment on Ubuntu 26.04, most readers should default to 9.x — but there are legitimate reasons to stay on 8.x.
| Criteria | Elasticsearch 9.x | Elasticsearch 8.x |
|---|---|---|
| Current version (as of mid-2026) | 9.4.1 | 8.19.15 |
| Best for | New self-managed deployments | Existing 8.x clusters, pinned plugins/clients |
| Support horizon | Current major branch | Supported through July 15, 2027 |
| APT repository path | https://artifacts.elastic.co/packages/9.x/apt | https://artifacts.elastic.co/packages/8.x/apt |
| Config format | DEB822 .sources recommended | Legacy .list still works |
| Java requirement | Bundled OpenJDK | Bundled OpenJDK |
| Security defaults | TLS + auth enabled out of the box | TLS + auth enabled out of the box |
This guide defaults to Elasticsearch 9.x. If you need to stay on 8.x for compatibility reasons, swap 9.x for 8.x in the repository URL in Step 3 — every other step is identical.
Prerequisites
- A server running Ubuntu 26.04 LTS with
sudoprivileges - At least 2 GB RAM (4 GB+ recommended for anything beyond testing)
- At least 10 GB free disk space
- A non-root user configured with
sudo - Outbound HTTPS access to
artifacts.elastic.co
Architecture Overview
A minimal single-node Elasticsearch deployment on Ubuntu looks like this:
┌─────────────────────────────┐
│ Ubuntu 26.04 LTS │
│ │
Client / App──HTTPS ──▶│ ┌────────────────────────┐ │
(port 9200) │ │ Elasticsearch 9.x │ │
│ │ systemd service │ │
│ │ │ │
│ │ ┌────────────────────┐ │ │
│ │ │ JVM (bundled JDK) │ │ │
│ │ │ Heap: -Xms/-Xmx │ │ │
│ │ └────────────────────┘ │ │
│ │ │ │
│ │ Data: /var/lib/ │ │
│ │ elasticsearch │ │
│ │ Logs: /var/log/ │ │
│ │ elasticsearch │ │
│ │ Config:/etc/ │ │
│ │ elasticsearch │ │
│ └────────────────────────┘ │
│ │
│ UFW: allow 9200 (scoped) │
└─────────────────────────────┘
For multi-node clusters, replicate this block per node and configure discovery.seed_hosts and cluster.initial_master_nodes accordingly — a topic covered in a dedicated clustering article linked at the end.
Step 1: Update the System and Install Dependencies
sudo apt update && sudo apt upgrade -y
sudo apt install -y apt-transport-https curl gnupg
apt-transport-https ensures APT can pull packages over HTTPS, curl fetches the GPG key, and gnupg handles key verification.
Step 2: Import the Elastic GPG Key
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | \
sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
This stores Elastic’s signing key in /usr/share/keyrings/ rather than the deprecated global apt-key keyring, which APT on Ubuntu 26.04 no longer supports.
Step 3: Add the Elastic APT Repository
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | \
sudo tee /etc/apt/sources.list.d/elastic-9.x.list
Refresh the package index:
sudo apt update
If you specifically need the 8.x branch, replace 9.x with 8.x in both the URL and the filename above.
Step 4: Install Elasticsearch
sudo apt install elasticsearch -y
Elasticsearch ships with a bundled OpenJDK build, so there’s no separate Java installation step required. The package installer performs a security autoconfiguration pass automatically — TLS for the HTTP and transport layers is enabled, and authentication is turned on by default.
Step 5: Save the Auto-Generated Security Credentials
During installation, watch the terminal output for a block similar to:
--------------------------- 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-generated-password>
The generated enrollment token for Kibana instances: <your-enrollment-token>
----------------------------------------------------------------------------------------------------
Copy both values immediately — they scroll past quickly and are not stored in plain text anywhere else by default. If you miss them, you can reset the elastic user’s password later:
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
Step 6: Configure Elasticsearch (elasticsearch.yml)
Open the main configuration file:
sudo nano /etc/elasticsearch/elasticsearch.yml
For a single-node development or small production instance, set:
cluster.name: bckinfo-es-cluster
node.name: node-1
network.host: 0.0.0.0
discovery.type: single-node
network.host: 0.0.0.0 binds Elasticsearch to all interfaces — fine behind a firewall or private network, but pair it with UFW rules (Step 10) or a reverse proxy before exposing the server publicly. For a strictly local instance, use network.host: localhost instead.
Step 7: Tune the JVM Heap Size
Elasticsearch’s default heap sizing is conservative. Edit the JVM options:
sudo nano /etc/elasticsearch/jvm.options.d/heap.options
Add explicit -Xms and -Xmx values set to the same size, at roughly 50% of available system RAM, and never exceeding ~31 GB (to stay under the compressed-pointers threshold):
-Xms2g
-Xmx2g
Save and exit. This file is picked up automatically on the next service start.
Step 8: Start and Enable the Service
sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch
Check the service state:
sudo systemctl status elasticsearch
You should see active (running).
Step 9: Verify the Installation
Query the local HTTPS endpoint using the elastic superuser credentials saved in Step 5:
curl --cacert /etc/elasticsearch/certs/http_ca.crt \
-u elastic:<your-generated-password> \
https://localhost:9200
A healthy response looks like:
{
"name" : "node-1",
"cluster_name" : "bckinfo-es-cluster",
"version" : {
"number" : "9.4.1",
"build_flavor" : "default"
},
"tagline" : "You Know, for Search"
}
You can also confirm the installed package and binary version directly:
apt-cache policy elasticsearch
sudo /usr/share/elasticsearch/bin/elasticsearch --version
Step 10: Configure the Firewall (UFW)
If Elasticsearch only needs to be reachable from specific hosts (an application server, a Kibana instance, or a monitoring tool), scope the rule instead of opening 9200 to the world:
sudo ufw allow from <trusted-ip> to any port 9200 proto tcp
sudo ufw enable
sudo ufw status
For a fully local, single-machine setup, skip this step entirely and keep network.host: localhost.
Optional: Install Kibana
Kibana uses the same APT repository and GPG key you already configured:
sudo apt install kibana -y
sudo systemctl enable --now kibana
Retrieve a Kibana enrollment token if you didn’t save the one shown during the Elasticsearch install:
sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
Then open http://<server-ip>:5601 in a browser and paste the token to complete setup.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
systemctl status elasticsearch shows failed | Insufficient memory or heap misconfiguration | Check journalctl -u elasticsearch --no-pager | tail -50; lower -Xms/-Xmx in heap.options |
max virtual memory areas vm.max_map_count [65530] is too low | Kernel vm.max_map_count below required threshold | Run sudo sysctl -w vm.max_map_count=262144 and persist it in /etc/sysctl.conf |
curl: (60) SSL certificate problem | Missing or wrong CA cert path | Point --cacert to /etc/elasticsearch/certs/http_ca.crt |
401 Unauthorized on API calls | Wrong or lost elastic password | Run elasticsearch-reset-password -u elastic |
| Service starts but port 9200 unreachable remotely | network.host still set to localhost, or UFW blocking the port | Update elasticsearch.yml and add the appropriate UFW rule |
apt update fails to fetch the Elastic repo | GPG key not linked correctly in the .list file | Re-verify the signed-by path matches the keyring file exactly |
| High memory pressure / OOM kills | Heap set too close to total system RAM | Keep heap at ~50% of RAM, leaving room for the OS file cache |
Removing Elasticsearch
To fully remove Elasticsearch and its data:
sudo systemctl stop elasticsearch
sudo apt purge elasticsearch -y
sudo rm -rf /var/lib/elasticsearch /var/log/elasticsearch /etc/elasticsearch
sudo apt autoremove -y
Related Reading on bckinfo.com
- How to Deploy PostgreSQL on Kubernetes with Persistent Storage
- Kubernetes Network Policies Explained: Secure Pod-to-Pod Communication
- Prometheus + Grafana installation guide
- Docker Security Best Practices







