# How to Use the Official Elasticsearch Docker Container: A Complete Guide

> Learn to use the official Elasticsearch Docker container for development or production. This guide covers single-node setups and multi-node cluster orchestration with Docker Compose.

- Repository: [elastic/elasticsearch](https://github.com/elastic/elasticsearch)
- Tags: tutorial
- Published: 2026-02-12

---

**You can run the official Elasticsearch Docker container using `docker run -d -p 9200:9200 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:latest` for quick development, or orchestrate multi-node production clusters with Docker Compose.**

The official Elasticsearch Docker container provides a production-ready, isolated environment for running Elasticsearch nodes without requiring a local Java installation. Maintained in the `elastic/elasticsearch` repository, this image packages the full distribution with default configurations located in `/usr/share/elasticsearch/config` and data storage at `/usr/share/elasticsearch/data`. Whether you need a single-node instance for local development or a clustered deployment, the official Elasticsearch Docker container supports both scenarios through environment variables and volume mounts.

## What Is the Official Elasticsearch Docker Image?

The official image is published on Elastic’s Docker registry at `docker.elastic.co/elasticsearch/elasticsearch`. Each tag corresponds to a specific Elasticsearch release (e.g., `9.3.0`, `8.15.0`). The image build process is defined in `distribution/docker/src/docker/dockerfiles/default/Dockerfile`, which copies the Elasticsearch distribution, sets up the entrypoint script, and configures default environment variables. When you pull this image, you receive a fully configured Elasticsearch distribution that follows the same default settings and plugins as a binary installation, but isolated within a container.

## Quick Start with the Official Elasticsearch Docker Container

### Single-Node Development Setup

For local development and testing, run a single-node cluster with security disabled:

```bash
docker run -d \
  --name elasticsearch \
  -p 9200:9200 -p 9300:9300 \
  -e "discovery.type=single-node" \
  -e "xpack.security.enabled=false" \
  -v esdata:/usr/share/elasticsearch/data \
  docker.elastic.co/elasticsearch/elasticsearch:9.3.0

```

| Flag | Purpose |
|------|---------|
| `-d` | Run container in background |
| `--name` | Assign a friendly container name |
| `-p 9200:9200 -p 9300:9300` | Expose HTTP and transport ports to the host |
| `-e "discovery.type=single-node"` | Disable cluster discovery for single-node operation |
| `-e "xpack.security.enabled=false"` | Turn off X-Pack security for quick testing |
| `-v esdata:/usr/share/elasticsearch/data` | Persist data using a named Docker volume |

## Configuring the Official Elasticsearch Docker Container

### Environment Variables and JVM Options

The container accepts standard Elasticsearch environment variables to override configuration without editing files. Key variables include:

- `discovery.type` – Set to `single-node` for development or omit for production clustering
- `xpack.security.enabled` – Control the security plugin (`true` or `false`)
- `ELASTIC_PASSWORD` – Set the built-in `elastic` superuser password when security is enabled
- `ES_JAVA_OPTS` – Pass JVM options such as heap size (e.g., `-Xms1g -Xmx1g`)

Default JVM options are defined in `distribution/docker/src/docker/dockerfiles/default/jvm.options`, but you can override these at runtime via `ES_JAVA_OPTS`.

### Mounting Custom Configuration Files

For advanced setups, mount a host directory containing [`elasticsearch.yml`](https://github.com/elastic/elasticsearch/blob/main/elasticsearch.yml), `jvm.options`, or TLS certificates to `/usr/share/elasticsearch/config`:

```bash
docker run -d \
  --name elasticsearch \
  -p 9200:9200 \
  -v /path/to/custom/config:/usr/share/elasticsearch/config \
  -v esdata:/usr/share/elasticsearch/data \
  docker.elastic.co/elasticsearch/elasticsearch:9.3.0

```

The base configuration applied when the container starts is defined in [`distribution/docker/src/docker/dockerfiles/default/elasticsearch.yml`](https://github.com/elastic/elasticsearch/blob/main/distribution/docker/src/docker/dockerfiles/default/elasticsearch.yml). When you mount a custom configuration directory, files present in that directory replace the defaults entirely.

## Production Deployment Patterns

### Multi-Node Cluster with Docker Compose

For production workloads, run a multi-node cluster using Docker Compose. The example below creates a three-node cluster with proper discovery and memory locking:

```yaml
version: "3.8"

services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.3.0
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - ES_JAVA_OPTS=-Xms2g -Xmx2g
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
    volumes:
      - es01data:/usr/share/elasticsearch/data

  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.3.0
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - ES_JAVA_OPTS=-Xms2g -Xmx2g
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es02data:/usr/share/elasticsearch/data

  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.3.0
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - ES_JAVA_OPTS=-Xms2g -Xmx2g
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es03data:/usr/share/elasticsearch/data

volumes:
  es01data:
  es02data:
  es03data:

```

Start the cluster with `docker compose up -d`. The nodes discover each other via `discovery.seed_hosts` and elect a master automatically. This configuration aligns with the example Compose file found in [`distribution/docker/src/docker/docker-compose.yml`](https://github.com/elastic/elasticsearch/blob/main/distribution/docker/src/docker/docker-compose.yml) within the source repository.

### Security and Memory Configuration

For production deployments, enable X-Pack security and configure TLS:

- Set `xpack.security.enabled=true` and provide `ELASTIC_PASSWORD` for the elastic user
- Mount TLS certificates to `/usr/share/elasticsearch/config/certs`
- Enable `bootstrap.memory_lock=true` to prevent JVM heap swapping, paired with `ulimits` for `memlock`

## Troubleshooting Common Issues

| Symptom | Solution |
|---------|----------|
| Container exits immediately | Verify `ES_JAVA_OPTS` heap settings fit within Docker memory limits; check host cgroup constraints. |
| Port 9200 unreachable | Confirm `-p 9200:9200` mapping exists and host firewall rules allow traffic. |
| Data loss after restart | Ensure you mount a Docker volume or host directory to `/usr/share/elasticsearch/data`; otherwise data persists only in the container layer. |
| Security plugin errors | When enabling X-Pack, provide `ELASTIC_PASSWORD` or mount a complete [`elasticsearch.yml`](https://github.com/elastic/elasticsearch/blob/main/elasticsearch.yml) with security settings. |
| Cluster health RED | Check container logs (`docker logs elasticsearch`) for disk watermark breaches, JVM heap issues, or discovery failures. |

## Summary

- The **official Elasticsearch Docker container** is hosted at `docker.elastic.co/elasticsearch/elasticsearch` and built from `distribution/docker/src/docker/dockerfiles/default/Dockerfile`.
- For development, run a **single-node cluster** with `discovery.type=single-node` and `xpack.security.enabled=false`, always mounting a volume to `/usr/share/elasticsearch/data` for persistence.
- **Configuration** is handled via environment variables (`ES_JAVA_OPTS`, `ELASTIC_PASSWORD`) or by mounting custom files to `/usr/share/elasticsearch/config`, overriding defaults from [`distribution/docker/src/docker/dockerfiles/default/elasticsearch.yml`](https://github.com/elastic/elasticsearch/blob/main/distribution/docker/src/docker/dockerfiles/default/elasticsearch.yml).
- **Production deployments** require multi-node clusters with proper `discovery.seed_hosts`, `bootstrap.memory_lock=true`, and dedicated volumes per node.

## Frequently Asked Questions

### Where is the official Elasticsearch Docker image hosted?

The official image is published on Elastic’s Docker registry at `docker.elastic.co/elasticsearch/elasticsearch`, not on Docker Hub. You must specify the full registry path when pulling or running the container, and you can append version tags like `:9.3.0` or `:8.15.0` to pin a specific release.

### How do I persist data when using the Elasticsearch Docker container?

By default, the container stores data at `/usr/share/elasticsearch/data` inside the container filesystem. To prevent data loss when the container restarts, mount a Docker named volume or a host directory to this path using `-v esdata:/usr/share/elasticsearch/data` in docker run commands, or define volumes in your Docker Compose file.

### What ports does the official Elasticsearch Docker container expose?

The container exposes two primary ports: **9200** for HTTP REST API traffic and **9300** for internal transport communication between nodes. When running locally, map port 9200 to the host to access the API from your machine. In multi-node clusters, expose 9300 only on the internal Docker network unless connecting external nodes.

### How do I disable security for local development?

Set the environment variable `xpack.security.enabled=false` when starting the container. This disables X-Pack security features including authentication and TLS, allowing you to connect to Elasticsearch without credentials. Never disable security in production environments; instead, configure TLS certificates and set the `ELASTIC_PASSWORD` environment variable for the built-in `elastic` user.