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
Returns cluster info JSON if running | Cluster health: /_cluster/health | Kibana UI: :5601
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
| Component | Port | Role |
|---|---|---|
| Elasticsearch | 9200 | Store and index log data |
| Logstash | 5044 (input), 9600 (API) | Ingest, parse, and transform logs |
| Kibana | 5601 | Search and visualize data |
| Filebeat / Metricbeat | — | Lightweight log/metric shippers |
Troubleshooting
| Problem | Fix |
|---|---|
| curl returns "unauthorized" or SSL error | Elasticsearch 8 has security on — add -e "xpack.security.enabled=false" in Docker, or configure proper credentials |
| Container exits immediately | Elasticsearch 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 found | Indices are case-sensitive and must be created before indexing documents (auto-creation is on by default) |
| Slow queries | Add mappings to specify field types — dynamic mapping works but explicit mappings improve performance |