Categories: Tools

Setting JVM options for an Elasticsearch service run in a Docker container

Default minimum and maximum heap size used by Elasticsearch is set to 1GB. I want to show you how you can modify this value when running the service with Docker.

What to do if you don’t want to create your own jvm.options file

Any value we set in ES_JAVA_OPTS will override a heap size set by the default jvm.options file.

While setting the heap size via bind-mounted JVM options is the recommended method, you can also configure this by using the ES_JAVA_OPTS environment variable (…)

https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-set-heap-size

Run ElasticSearch with Docker Compose

To keep our configuration clean and readable we use the .env file with the following environment variables:

# .env
COMPOSE_PROJECT_NAME=elasticsearch-example
ELASTIC_STACK_VERSION=7.6.2
JAVA_OPTS=-Xmx256m -Xms256m

As you can see, I set the minimum and maximum size to be even smaller than the default value. We know that:

Elasticsearch will assign the entire heap specified in jvm.options (…)

https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html#heap-size

Therefore, if we want to run the example service on a local machine just to tinker with settings, we can start with using as little resources as possible. In the production environment we’ll folllow the guideances and set the Xmx and Xms to bigger values (but no more than 50% of available physical RAM). Remember that both values should be equal.

A simple container configuration is enclosed in the following docker-compose.yml file:

# docker.yml
version: "3.3"
services:
  elasticsearch:
    image: elasticsearch:$ELASTIC_STACK_VERSION
    volumes:
      - elasticsearch:/usr/share/elasticsearch/data
    environment:
      ES_JAVA_OPTS: $JAVA_OPTS
      # Change discovery type to enable the production mode and bootstrap checks
      discovery.type: single-node
    ports:
      - "9200:9200"
    networks:
      - internal

networks:
  internal:

volumes:
  elasticsearch:

Run the following command in the console to start the service:

$ docker-compsoe up -d

Verify whether the heap size was set according to your configuration

If you use IntelliJ, verifying container setup is effortless thanks to the Docker support:

If you don’t, enter the container by using the command shown below:

$ docker exec -it elasticsearchexample_1 /bin/bash

We can confirm that our settings have been applied by browsing the container logs:

{
   "type":"server",
   "timestamp":"2020-05-02T11:52:41,968Z",
   "level":"INFO",
   "component":"o.e.e.NodeEnvironment",
   "cluster.name":"docker-cluster",
   "node.name":"c17c952f0e3e",
   "message":"heap size [247.5mb], compressed ordinary object pointers [true]"
}
…
{
   …
   "message":"JVM arguments [… -Xmx256m, -Xms256m, …]"
}

Creating your custom jvm.options file

You can see the defaults by checking the content of the jvm.otpions file inside the container. On the screenshot below you can see how to get to a file inside a Docker container with IntelliJ:

You can use this file to create your custom settings. Once you have your jvm.options file ready, just mount it in the docker-compose.yml file under the /usr/share/elasticsearch/config/jvm.options.d path.

Useful resources

Photo by Ishan @seefromthesky on StockSnap

little_pinecone

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago