ElasticSearch on Docker

This article talks about how to run ElasticSearch on docker. And should be used only for developer environment.
We will talk about how to run Elastic that persists data between runs, and how to run Elastic that starts as fresh every time you run.

What is not covered
- docker
- elastic search

What is covered
- ElasticSearch Image & Container
- Testing
- Does data persist across container restart
- Starting ElasticSearch with a clean slate
- Persisting data across containers

ElasticSearch Image & Container

We shall use official docker image of ElasticSearch hosted on https://hub.docker.com/_/elasticsearch.
Latest tag as of writing this doc is 7.3.1.
So we do
    docker pull elasticsearch:7.3.1

As per documentation on github, we run ElasticSearch as
    docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.3.1

That was simple.

[Update: March 11, 2021]
With ElasticSearch version 8.1.0 I have seen security measures implemented. But as a developer, testing out a few things, I do not need these security measures. So we just turn OFF these security measures as 
    docker run -d --name elastic8 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "xpack.security.enabled=false" elasticsearch:8.1.0
The important part was -e "xpack.security.enabled=false".

Testing

Get all the indexes
    curl -X GET http://localhost:9200/_cat/indices?v=&pretty=

Output is a single line which just look like headers. It means that our index is empty.

So we create an index
    curl -X PUT http://localhost:9200/myindex?pretty= -H 'Content-Type: application/json'

Now if you try to get all indexes, you can see it there.

Put a few messages in index
    curl -X PUT http://localhost:9200/myindex/person/1?pretty= -H 'Content-Type: application/json' -d '{"name": "John Cena","occupation": "wrestler"}'
    curl -X PUT http://localhost:9200/myindex/person/2?pretty= -H 'Content-Type: application/json' -d '{"name": "Bear Grylls","occupation": "adventurer"}'

Now to see whether index holds our data
    curl -X GET http://localhost:9200/myindex/_search?q=*&pretty=

You should see both John Cena and Bear Grylls.

Does data persist across container restart

There are a few times when we wish to start with a clean slate. Only a few times. Most of the times we wish to retain our data.

Shutdown elasticsearch server
    docker stop elasticsearch
Start elasticsearch server again
    docker start elasticsearch

Now use curl from testing to see indexes. And yes, it exists.
If you do not see anything, then wait for some time. ElasticSearch may take some time to boot up and try again.

A docker container retains data. i.e. any file change made on container when running remains there.So when we start container back up, data is there.

According to documentation, ElasticSearch stores data at location: /usr/share/elasticsearch/data

Starting ElasticSearch with a clean slate

Wish to start with a clean slate?
Simply delete the container.
    docker stop elasticsearch
    docker rm elasticsearch

And recreate it as we did before.
That will give us a clean slate.

Persisting data across containers

It may so happen that a new docker image of elastic search is out. You wish to try it out, but can't because you would lose all your data.

Or in other words, retaining elastic search data across containers. (Can come handy if you wish to try out cluster)

Solution: docker volumes
Docker volumes are of 2 types:
1. persistent (stored on your host drive)
2. ephimeral (managed only by docker - seen only by docker.)

Ephimeral has a disadvantage against persistent - you can remove it using docker commands. Or it would be lost if you uninstall docker.

Lets try with ephimeral volumes. Persisten volumes can be used the same way.

Create a docker volume:
    docker volume create elasticsearch-volume

See if volume is created
    docker volume ls | grep elasticsearch-volume

Now start elasticsearch container a little bit differently i.e. tell it that it needs to use a volume
    docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v elasticsearch-volume:/usr/share/elasticsearch/data elasticsearch:7.3.1
Notice highlighted part. Here I tell container to use elasticsearch-volume and mount it where ElasticSearch stores it's data.

Now you can delete container, and then recreate it. Remember to point to same volume.

Conclusion

ElasticSearch docker image is pretty simple. And is documentation pretty good.
Using a docker image instead of an elasticsearch installation is easy and gives control if you do not have install rights on dev machine.

Comments