Port 9200 — Elasticsearch

Elasticsearch is a distributed full-text search and analytics engine built on Apache Lucene. Port 9200 is its REST/HTTP interface — the API through which you index documents, run queries, and administer the cluster. Port 9300 handles internal cluster communication (node-to-node transport). In local development, you only interact with port 9200.

Elasticsearch stores data in indices (similar to database tables), and each record is a JSON document. Its strength is full-text search, aggregations, and near-real-time analytics over large datasets. It's the "E" in the ELK stack (Elasticsearch, Logstash, Kibana).

Elasticsearch API: localhost:9200

Install Elasticsearch

# Docker (simplest for dev)
docker run -d \
  --name elasticsearch \
  -p 9200:9200 \
  -p 9300:9300 \
  -e "discovery.type=single-node" \
  -e "xpack.security.enabled=false" \
  -v es_data:/usr/share/elasticsearch/data \
  elasticsearch:8.12.0

# Verify it's running
curl http://localhost:9200
# → Returns cluster name, version, cluster UUID
Elasticsearch 8.x security: Elasticsearch 8 enables security by default — HTTPS and authentication required. The xpack.security.enabled=false flag disables this for local development. In production, keep security enabled.

Core REST API Operations

# Check cluster health
curl http://localhost:9200/_cluster/health?pretty

# List all indices
curl http://localhost:9200/_cat/indices?v

# Create an index with settings
curl -X PUT http://localhost:9200/products \
  -H 'Content-Type: application/json' \
  -d '{
    "settings": { "number_of_shards": 1, "number_of_replicas": 0 }
  }'

# Index a document (create or replace by ID)
curl -X PUT http://localhost:9200/products/_doc/1 \
  -H 'Content-Type: application/json' \
  -d '{"name": "Widget Pro", "price": 49.99, "category": "tools"}'

# Index a document (auto-generate ID)
curl -X POST http://localhost:9200/products/_doc \
  -H 'Content-Type: application/json' \
  -d '{"name": "Gadget Mini", "price": 19.99, "category": "accessories"}'

# Get a document by ID
curl http://localhost:9200/products/_doc/1?pretty

# Delete a document
curl -X DELETE http://localhost:9200/products/_doc/1

# Delete an index
curl -X DELETE http://localhost:9200/products

Search Queries

# Full-text search across all fields
curl -X GET http://localhost:9200/products/_search \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "match": { "name": "widget" }
    }
  }'

# Exact match (keyword / filter)
curl -X GET http://localhost:9200/products/_search \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "term": { "category": "tools" }
    }
  }'

# Range query
curl -X GET http://localhost:9200/products/_search \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "range": { "price": { "gte": 10, "lte": 50 } }
    }
  }'

# Multi-field search with relevance boosting
curl -X GET http://localhost:9200/products/_search \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "multi_match": {
        "query": "widget",
        "fields": ["name^3", "description"]
      }
    }
  }'

Python Client

from elasticsearch import Elasticsearch

es = Elasticsearch("http://localhost:9200")

# Index a document
es.index(index="products", id=1, body={"name": "Widget Pro", "price": 49.99})

# Search
results = es.search(index="products", body={
    "query": {"match": {"name": "widget"}}
})
for hit in results["hits"]["hits"]:
    print(hit["_source"]["name"], hit["_score"])

ELK Stack — Full Logging Pipeline

ComponentPortRole
Elasticsearch9200Store and index log data
Logstash5044 (input), 9600 (API)Ingest, parse, and transform logs
Kibana5601Search and visualize data
Filebeat / MetricbeatLightweight log/metric shippers

Troubleshooting

ProblemFix
curl returns "unauthorized" or SSL errorElasticsearch 8 has security on — add -e "xpack.security.enabled=false" in Docker, or configure proper credentials
Container exits immediatelyElasticsearch needs at least 1GB heap — check Docker memory limits (docker stats)
vm.max_map_count too low (Linux)sudo sysctl -w vm.max_map_count=262144 — required for Elasticsearch to run on Linux
Index not foundIndices are case-sensitive and must be created before indexing documents (auto-creation is on by default)
Slow queriesAdd mappings to specify field types — dynamic mapping works but explicit mappings improve performance