Single Node Elasticsearch

GitHub

Deploy a single Elasticsearch node using Docker Compose.

30m5m reading25m lab

Project Files

elasticsearch-single
Explorer
elasticsearch-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    container_name: elasticsearch
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
      - 9300:9300
    env_file:
      - .env
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - network.host=0.0.0.0
      - transport.host=0.0.0.0
      - node.name=algo-es-node
      - cluster.name=${CLUSTER_NAME}
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - xpack.security.enabled=false
      - xpack.license.self_generated.type=${LICENSE}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
      interval: 10s
      timeout: 10s
      retries: 120
volumes:
  esdata:
#     driver: local
#     driver_opts:
#       o: bind
#       type: none
#       device: /mt/sda/es-data
YAMLUTF-8
Ln 392 files

Configuration

Download both files into a new folder — they work together. See Docker Compose environment variables and Elasticsearch important settings for full reference.

elasticsearch-compose.yml — environment

environment:
  - "ES_JAVA_OPTS=-Xms512m -Xmx512m"              # JVM heap — set to half of MEM_LIMIT
  - network.host=0.0.0.0                           # bind REST API to all interfaces
  - transport.host=0.0.0.0                         # bind inter-node transport to all interfaces
  - node.name=algo-es-node                         # node label shown in cluster stats
  - cluster.name=${CLUSTER_NAME}                   # nodes with the same name form a cluster
  - discovery.type=single-node                     # skip master election for one-node setup
  - bootstrap.memory_lock=true                     # pin JVM heap in RAM — prevent OS swap
  - xpack.security.enabled=false                   # no TLS/auth — development only
  - xpack.license.self_generated.type=${LICENSE}

.env

STACK_VERSION=9.3.0
CLUSTER_NAME=vbv-ec-cluster
LICENSE=basic              # trial = 30-day enterprise features
MEM_LIMIT=1073741824       # bytes — set to 50% of your available RAM (1 GB shown)
ES_PORT=9200               # change if port is in use
KIBANA_PORT=5601           # used by Kibana — change if port is in use
💡

Tip: MEM_LIMIT is in bytes. 2 GB = 2147483648, 4 GB = 4294967296, 8 GB = 8589934592.


Deploy

  1. 1 Use Download All in the Project Files section above to save both files into a new folder, e.g. elasticsearch-single/
  2. 2 Open .env and update MEM_LIMIT to 50% of your available RAM
  3. 3 Open a terminal in that folder
# Linux only — macOS Docker Desktop handles this internally
sudo sysctl -w vm.max_map_count=262144

docker compose -f elasticsearch-compose.yml up -d

Watch the container start:

watch docker ps

Expected when healthy:

CONTAINER ID   IMAGE                           STATUS
abc123         elasticsearch:9.3.0             Up 2 min (healthy)

Verify

curl -X GET "localhost:9200/_cluster/health?pretty"

Expected response:
{
  "cluster_name" : "vbv-ec-cluster",
  "status" : "green",           # green = all shards assigned | yellow = replicas unassigned | red = data missing
  "number_of_nodes" : 1,        # 1 = one node, as configured
  "number_of_data_nodes" : 1,
  "unassigned_shards" : 0       # 0 = nothing waiting for placement
}

Common Issues

max_map_count error (Linux only)

# Error
max virtual memory areas vm.max_map_count [65530] is too low

# Fix
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
ℹ️

Note: Only happens on Linux. Elasticsearch uses mmap for index segments — the Linux default (65530) is too low. Docs

Memory lock warning

# Warning in logs
Unable to lock JVM Memory: error=12, reason=Cannot allocate memory

# Fix — lower MEM_LIMIT in .env to free up headroom, then restart
docker compose -f elasticsearch-compose.yml down && docker compose -f elasticsearch-compose.yml up -d

Port already in use

# Check what's using it
lsof -i :9200

# Or change ES_PORT in .env
ES_PORT=9201

Next Steps

Discussion