{"id":2062,"date":"2021-05-07T10:30:19","date_gmt":"2021-05-07T07:30:19","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/install-configure-elasticsearch\/"},"modified":"2026-04-23T14:18:17","modified_gmt":"2026-04-23T13:18:17","slug":"install-configure-elasticsearch","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/install-configure-elasticsearch\/","title":{"rendered":"How to install and configure Elasticsearch"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Elasticsearch is a distributed, RESTful search and analytics engine capable of addressing a growing number of use cases. It provides a multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents all with easy installation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Elasticsearch serves as the heart of the Elastic Stack by storing your data for lightning-fast search, fine\u2011tuned relevancy, and powerful analytics that scale with ease.&nbsp;With Elasticsearch, you can perform and combine many types of searches giving you the freedom to work as you want.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this tutorial, we\u2019ll show you how to quickly and easily install and configure Elasticsearch on a single Cloud Server with the possibility to scale out as needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deploying a new Cloud Server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To get started installing Elasticsearch, you will first need to deploy a Cloud Server with Ubuntu 20.04 or 18.04. Log into your <a href=\"https:\/\/hub.upcloud.com\/deploy\" target=\"_blank\" rel=\"noopener\">UpCloud Control Panel<\/a> and click the Deploy server button.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you are new to UpCloud, you can get started by <a href=\"https:\/\/signup.upcloud.com\/\" target=\"_blank\" rel=\"noopener\">signing up for the free trial<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The deployment page shows a number of options for customizing your new Cloud Server.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Choose the server location from the available data centres<\/li>\n\n\n\n<li>Pick a configuration, the \u20ac13 per month plan is a good starting point<\/li>\n\n\n\n<li>Select your operating system e.g. Ubuntu 20.04 or 18.04<\/li>\n\n\n\n<li>Add any SSH keys you want to use<\/li>\n\n\n\n<li>Give your server a hostname and description<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can find more in-depth <a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/deploy-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">deployment instructions<\/a> in a separate tutorial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing Elasticsearch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once your Cloud Server is up and running, connect to it using SSH. Afterwards, you can get started by adding the Elasticsearch repository.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">wget -qO - https:\/\/artifacts.elastic.co\/GPG-KEY-elasticsearch | sudo apt-key add -<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">echo \"deb https:\/\/artifacts.elastic.co\/packages\/7.x\/apt stable main\" | sudo tee -a \/etc\/apt\/sources.list.d\/elastic-7.x.list<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, update the repo lists to include the new source.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt update<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then install Elasticsearch with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt install elasticsearch<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When the installation is done, you will likely want to configure Elasticsearch for your use case. Head over to the next section to continue.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring Elasticsearch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After installing Elasticsearch, you are almost ready to get cracking. However, depending on your use case and requirements, you might want to have a look at the settings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open the <em>elasticsearch.yml<\/em> file in a text editor.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/elasticsearch\/elasticsearch.yml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">First things first, you should name your cluster and the node you are configuring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A node can only join a cluster if it shares the <em>cluster.name<\/em> with all the other nodes in the cluster. You should name your cluster appropriately to describe the purpose of the cluster.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># -------------------------------- Cluster ----------------------------------\n#\n# Use a descriptive name for your cluster:\n#\ncluster.name: example-cluster\n#<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>node.name<\/em> is used as a human-readable identifier for the nodes in the Elasticsearch cluster. By default, the <em>node.name<\/em> is set to the hostname of the server but can be configured manually.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># --------------------------------- Node ------------------------------------\n#\n# Use a descriptive name for the node:\n#\nnode.name: node-1\n#\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">By default, Elasticsearch is only accessible from localhost or the IP address 127.0.0.1. If you want to query it from another server or your local computer, you\u2019ll need to set the <em>network.host<\/em> to an appropriate IP address.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># -------------------------------- Network ----------------------------------\n#\n# By default Elasticsearch is only accessible on localhost. Set a different\n# address here to expose this node on the network:\n#\n#network.host: 192.168.0.1\n#<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You also have the option to change the default port 9200 according to your preferences. If you do set a custom port, remember to configure your firewall accordingly.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># By default Elasticsearch listens for HTTP traffic on the first free port it\n# finds starting at 9200. Set a specific HTTP port here:\n#\n#http.port: 9200\n#\n# For more information, consult the network module documentation.<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once you are done with the settings, save the file and exit the editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then start the Elasticsearch service and enable it to start at boot.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl start elasticsearch\nsudo systemctl enable elasticsearch<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The startup might take a few seconds but should complete without issue or output. Afterwards, you can check the status of the service with the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl status elasticsearch<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With the Elasticsearch service running, continue with firewall configuration before getting to testing the search.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring firewall rules<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you enabled Elasticsearch on a public network, you should restrict access to the HTTP query port 9200 to just your IP addresses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Replace the <em>&lt;your-ip-address&gt;<\/em> in the following command with your public IP or the public IP of another server.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ufw allow from &lt;your-ip-address&gt; to any port 9200<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Repeat the above allow command to include other IP addresses from where you want to have access.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also, make sure to allow SSH connections to make sure you are not locked out from your server.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ufw allow ssh<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then enable the firewall and verify the enabled rules by checking the firewall status.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ufw enable<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ufw status<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">Status: active\n\nTo                         Action      From\n--                         ------      ----\n9200                       ALLOW       &lt;your-ip-address&gt;\n22                         ALLOW       Anywhere\n22 (v6)                    ALLOW       Anywhere (v6)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With the firewall configured, you can be sure unauthorised access attempts won\u2019t get through.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Follow up by testing the Elasticsearch yourself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the connection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The simplest way to query the Elasticsearch server is to use curl or another similar command-line HTTP tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The following example command allows you to get the server details. Note that localhost is only accessible from within the Cloud Server itself. Replace the localhost with the public IP of the Cloud Server if you want to query Elasticsearch from an external source.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X GET 'http:\/\/localhost:9200'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"name\" : \"elastic.example.com\",\n  \"cluster_name\" : \"elasticsearch\",\n  \"cluster_uuid\" : \"NCY3941lRtWECJTI_fASlw\",\n  \"version\" : {\n    \"number\" : \"7.12.1\",\n    \"build_flavor\" : \"default\",\n    \"build_type\" : \"deb\",\n    \"build_hash\" : \"3186837139b9c6b6d23c3200870651f10d3343b7\",\n    \"build_date\" : \"2021-04-20T20:56:39.040728659Z\",\n    \"build_snapshot\" : false,\n    \"lucene_version\" : \"8.8.0\",\n    \"minimum_wire_compatibility_version\" : \"6.8.0\",\n    \"minimum_index_compatibility_version\" : \"6.0.0-beta1\"\n  },\n  \"tagline\" : \"You Know, for Search\"\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can also make further queries using the indexes.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X GET 'http:\/\/localhost:9200\/_nodes\/node-1\/name?pretty'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note the <em>?pretty<\/em> parameter at the end which is used to format the output making it easier to read on the command line. Without that, all output will be printed into a single line.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Querying the database<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we have a working Elasticsearch node up and running, let\u2019s input some data we can use to test it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Create a new index<\/strong> with an attached message using the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X POST -H 'Content-Type: application\/json' 'localhost:9200\/example\/helloworld\/1?pretty' -d '{ \"message\": \"Hello world!\" }'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should get an output similar to the one below to confirm.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"_index\" : \"example\",\n  \"_type\" : \"helloworld\",\n  \"_id\" : \"1\",\n  \"_version\" : 1,\n  \"result\" : \"created\",\n  \"_shards\" : {\n    \"total\" : 2,\n    \"successful\" : 1,\n    \"failed\" : 0\n  },\n  \"_seq_no\" : 0,\n  \"_primary_term\" : 1\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Query the index<\/strong> directly for the input we just made by using the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X GET -H 'Content-Type: application\/json' 'localhost:9200\/example\/helloworld\/1?pretty'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"_index\" : \"example\",\n  \"_type\" : \"helloworld\",\n  \"_id\" : \"1\",\n  \"_version\" : 1,\n  \"_seq_no\" : 0,\n  \"_primary_term\" : 1,\n  \"found\" : true,\n  \"_source\" : {\n    \"message\" : \"Hello World!\"\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Search the database<\/strong> for the same data using the query below. The command is split between multiple lines for legibility, copy the whole thing as a single command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X POST -H 'Content-Type: application\/json' 'localhost:9200\/_search?pretty' -d'\n{\n  \"query\": {\n    \"match\": {\n      \"_type\": \"helloworld\"\n    }\n  }\n}'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"took\" : 25,\n  \"timed_out\" : false,\n  \"_shards\" : {\n    \"total\" : 1,\n    \"successful\" : 1,\n    \"skipped\" : 0,\n    \"failed\" : 0\n  },\n  \"hits\" : {\n    \"total\" : {\n      \"value\" : 1,\n      \"relation\" : \"eq\"\n    },\n    \"max_score\" : 1.0,\n    \"hits\" : [\n      {\n        \"_index\" : \"example\",\n        \"_type\" : \"helloworld\",\n        \"_id\" : \"1\",\n        \"_score\" : 1.0,\n        \"_source\" : {\n          \"message\" : \"Hello world!\"\n        }\n      }\n    ]\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The output of the search shows the number of hits your search had and lists the results.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also make changes to the data in the previous index.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Edit the index<\/strong> by changing the message with the next command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X PUT -H \"Content-Type: application\/json\" 'localhost:9200\/example\/helloworld\/1?pretty' -d '{ \"message\": \"Hello again!\" }'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"_index\" : \"example\",\n  \"_type\" : \"helloworld\",\n  \"_id\" : \"1\",\n  \"_version\" : 2,\n  \"result\" : \"updated\",\n  \"_shards\" : {\n    \"total\" : 2,\n    \"successful\" : 1,\n    \"failed\" : 0\n  },\n  \"_seq_no\" : 2,\n  \"_primary_term\" : 1\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then check that the changes were saved by querying the index again. E.g. with the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X GET -H \"Content-Type: application\/json\" 'localhost:9200\/example\/helloworld\/1?pretty'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"_index\" : \"example\",\n  \"_type\" : \"helloworld\",\n  \"_id\" : \"1\",\n  \"_version\" : 2,\n  \"_seq_no\" : 1,\n  \"_primary_term\" : 1,\n  \"found\" : true,\n  \"_source\" : {\n    \"message\" : \"Hello again!\"\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to remove the example data, you can remove the index it was stored in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Delete the index<\/strong> with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X DELETE 'localhost:9200\/example'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All done! Elasticsearch is working great and you should have an idea of the basic queries. Feel free to test the command further to get a better grasp of the search and indexes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Congratulations! You should now have a fully working Elasticsearch node up and running. A simple single-node setup is a quick way to get started with Elasticsearch which then offers the possibility to scale up with ease. In practice, interacting with Elasticsearch works the same regardless of the number of nodes thanks to the automated rebalancing and routing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Elasticsearch scale effortlessly across a cluster of any size making it able to easily handle even millions of events per second. It\u2019s&nbsp;capable of distributing data by dividing indices into shards with optional replicas.&nbsp;Each node hosts one or more shards and acts as a coordinator to delegate operations to an appropriate shard.<\/p>\n","protected":false},"author":3,"featured_media":28480,"comment_status":"open","ping_status":"closed","template":"","community-category":[223],"class_list":["post-2062","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2062"}],"version-history":[{"count":1,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2062\/revisions"}],"predecessor-version":[{"id":6447,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2062\/revisions\/6447"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2062"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}