How to install Elasticsearch on Ubuntu or Debian

Installing Elasticsearch on Ubuntu or Debian puts a local search and analytics node on the host for indexing application data, logs, and metrics, with the secured HTTP API ready for immediate testing once the service starts.

The official Debian package installs a bundled JVM, registers an Elasticsearch systemd unit, stores configuration in /etc/elasticsearch, writes data and logs to /var/lib/elasticsearch and /var/log/elasticsearch, and enables security auto-configuration the first time the node starts. That startup flow creates TLS material for the HTTP and transport layers and expects client checks to use HTTPS on port 9200.

Current package installation uses the 9.x APT repository and the /usr/share/keyrings/elasticsearch-keyring.gpg keyring path. The package scripts try to raise vm.max_map_count automatically, but current Elastic guidance expects 1048576, so confirming the value before the first full start avoids avoidable bootstrap problems on hosts where sysctl changes are skipped or overridden. Initial verification is best kept on localhost, because binding the node to non-local addresses or joining a multi-node cluster requires extra network and discovery changes.

Steps to install Elasticsearch on Ubuntu or Debian:

  1. Import the Elasticsearch package signing key into a dedicated APT keyring.
    $ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

    No command output indicates the keyring file was written successfully.

  2. Install apt-transport-https if the host still lacks HTTPS APT transport support.
    $ sudo apt-get install apt-transport-https
    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    apt-transport-https is already the newest version.

    Current Ubuntu releases already include HTTPS transport support, so this step is most relevant on older or minimal Debian systems.

  3. Save the official Elasticsearch APT repository definition.
    $ 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
    deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main
  4. Refresh the local APT package index.
    $ sudo apt-get update
    Get:1 https://artifacts.elastic.co/packages/9.x/apt stable InRelease [3249 B]
    Get:2 https://artifacts.elastic.co/packages/9.x/apt stable/main arm64 Packages [153 kB]
    ##### snipped #####
    Reading package lists... Done

    The architecture label in the package list line reflects the local host, such as amd64 or arm64.

  5. Install the Elasticsearch package.
    $ sudo apt-get install elasticsearch
    ##### snipped #####
    Setting up elasticsearch (9.3.2) ...
  6. Reload the systemd manager configuration so the new unit is available immediately.
    $ sudo systemctl daemon-reload

    Elastic's current Debian package instructions run this explicitly before enabling the service.

  7. Check the effective vm.max_map_count value.
    $ sysctl vm.max_map_count
    vm.max_map_count = 262144

    If the value is lower than 1048576, set it before starting Elasticsearch so current package guidance and bootstrap requirements are satisfied consistently.

  8. Persist the recommended vm.max_map_count value for Elasticsearch.
    $ echo "vm.max_map_count=1048576" | sudo tee /etc/sysctl.d/99-elasticsearch.conf
    vm.max_map_count=1048576

    The Debian package attempts to configure this automatically, but a local sysctl file keeps the value explicit and durable across overrides.

  9. Reload sysctl settings.
    $ sudo sysctl --system
    ##### snipped #####
    * Applying /etc/sysctl.d/99-elasticsearch.conf
  10. Enable the Elasticsearch service at boot.
    $ sudo systemctl enable elasticsearch.service
    Created symlink /etc/systemd/system/multi-user.target.wants/elasticsearch.service → /usr/lib/systemd/system/elasticsearch.service.
  11. Start the Elasticsearch service.
    $ sudo systemctl start elasticsearch.service
  12. Verify that Elasticsearch reached the running state.
    $ sudo systemctl status elasticsearch --no-pager
    ● elasticsearch.service - Elasticsearch
         Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; preset: enabled)
         Active: active (running) since Thu 2026-04-02 06:58:14 UTC; 18s ago
    ##### snipped #####

    When the node does not start cleanly, review /var/log/elasticsearch/elasticsearch.log for the application startup error instead of relying only on journalctl.

  13. Generate a fresh password for the built-in elastic superuser.
    $ sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -a
    This tool will reset the password of the [elastic] user to an autogenerated value.
    The password will be printed in the console.
    Please confirm that you would like to continue [y/N]y
    
    Password for the [elastic] user successfully reset.
    New value: sLH2nWSf*bzGnzBmHR33

    Store the generated password securely because the elastic user has full cluster access.

  14. Test the secured HTTP endpoint with the generated CA certificate and password.
    $ curl -u elastic https://localhost:9200
    Enter host password for user 'elastic':
    {
      "name" : "node-01",
      "cluster_name" : "elasticsearch",
      "version" : {
        "number" : "9.3.2"
      },
      "tagline" : "You Know, for Search"
    }

    Default self-managed package installs use HTTPS on port 9200, so plain HTTP requests will fail unless security has been reconfigured.