Loading

Using the Docker images in production

Self Managed

The following requirements and recommendations apply when running Elasticsearch in Docker in production, including some guidelines outlined in Important system configuration.

The following requirements and recommendations apply when running Elasticsearch in Docker in production.

The vm.max_map_count kernel setting must be set to at least 262144 for production use.

How you set vm.max_map_count depends on your platform.

By default, Elasticsearch runs inside the container as user elasticsearch using uid:gid 1000:0.

If you are bind-mounting a local directory or file, it must be readable by the elasticsearch user. In addition, this user must have write access to the config, data and log dirs (Elasticsearch needs write access to the config directory so that it can generate a keystore). A good strategy is to grant group access to gid 0 for the local directory.

Important

One exception is Openshift, which runs containers using an arbitrarily assigned user ID. Openshift presents persistent volumes with the gid set to 0, which works without any adjustments.

For example, to prepare a local directory for storing data through a bind-mount:

mkdir esdatadir
chmod g+rwx esdatadir
chgrp 0 esdatadir

You can also run an Elasticsearch container using both a custom UID and GID. You must ensure that file permissions will not prevent Elasticsearch from executing. You can use one of two options:

  • Bind-mount the config, data and logs directories. If you intend to install plugins and prefer not to create a custom Docker image, you must also bind-mount the plugins directory.
  • Pass the --group-add 0 command line option to docker run. This ensures that the user under which Elasticsearch is running is also a member of the root (GID 0) group inside the container.

Increased ulimits for nofile and nproc must be available for the Elasticsearch containers. Verify the init system for the Docker daemon sets them to acceptable values.

To check the Docker daemon defaults for ulimits, run:

docker run --rm docker.elastic.co/elasticsearch/elasticsearch:9.0.0 /bin/bash -c 'ulimit -Hn && ulimit -Sn && ulimit -Hu && ulimit -Su'

If needed, adjust them in the Daemon or override them per container. For example, when using docker run, set:

--ulimit nofile=65535:65535

Swapping needs to be disabled for performance and node stability. For information about ways to do this, see Disable swapping.

If you opt for the bootstrap.memory_lock: true approach, you also need to define the memlock: true ulimit in the Docker Daemon, or explicitly set for the container as shown in the sample compose file. When using docker run, you can specify:

-e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1

The image exposes TCP ports 9200 and 9300. For production clusters, randomizing the published ports with --publish-all is recommended, unless you are pinning one container per host.

By default, Elasticsearch automatically sizes JVM heap based on a nodes’s roles and the total memory available to the node’s container. We recommend this default sizing for most production environments. If needed, you can override default sizing by manually setting JVM heap size.

To manually set the heap size in production, bind mount a JVM options file under /usr/share/elasticsearch/config/jvm.options.d that includes your desired heap size settings.

For testing, you can also manually set the heap size using the ES_JAVA_OPTS environment variable. For example, to use 1GB, use the following command.

docker run -e ES_JAVA_OPTS="-Xms1g -Xmx1g" -e ENROLLMENT_TOKEN="<token>" --name es01 -p 9200:9200 --net elastic -it docker.elastic.co/elasticsearch/elasticsearch:9.0.0

The ES_JAVA_OPTS variable overrides all other JVM options. We do not recommend using ES_JAVA_OPTS in production.

Pin your deployments to a specific version of the Elasticsearch Docker image. For example:

docker.elastic.co/elasticsearch/elasticsearch:9.0.0

You should use a volume bound on /usr/share/elasticsearch/data for the following reasons:

  1. The data of your Elasticsearch node won’t be lost if the container is killed.
  2. Elasticsearch is I/O sensitive and the Docker storage driver is not ideal for fast I/O.
  3. It allows the use of advanced Docker volume plugins.

If you are using the devicemapper storage driver, do not use the default loop-lvm mode. Configure docker-engine to use direct-lvm.

Consider centralizing your logs by using a different logging driver. Also note that the default json-file logging driver is not ideally suited for production use.